コード例 #1
0
def create_vrf_default_rules(vrf_name, vrf_id, rule_id_list=None):
    for af in [socket.AF_INET, socket.AF_INET6]:
        any_ip_str = '0.0.0.0' if af == socket.AF_INET else '::'
        intf_list = ['lo']
        if vrf_name == 'default':
            intf_list.append('vdef-nsid%s' % str(vrf_id))
        else:
            intf_list.append('veth-nsid%s' % str(vrf_id))
        for intf in intf_list:
            rule_id = process_vrf_svcs_rule_add(
                VrfIncomingSvcsRule.RULE_TYPE_ACL,
                vrf_name,
                VrfIncomingSvcsRule.RULE_ACTION_ALLOW,
                af,
                src_ip=socket.inet_pton(af, any_ip_str),
                prefix_len=0,
                high_prio=True,
                in_intf=intf)
            if rule_id is None:
                log_err(
                    'Failed to create default ACL rules: VRF %s af %d intf %s'
                    % (vrf_name, af, intf))
                return False
            if rule_id_list is not None:
                log_info('Deault rule created: VRF %s af %d intf %s ID %d' %
                         (vrf_name, af, intf, rule_id))
                rule_id_list.append(rule_id)
    return True
コード例 #2
0
def test_rule_api():
    rid1 = cfg.process_vrf_svcs_rule_add(cfg.VrfSvcsRuleType.RULE_TYPE_ACL, 'test_management',
                                         cfg.VrfSvcsRuleAction.RULE_ACTION_DENY,
                                         socket.AF_INET,
                                         src_ip = socket.inet_pton(socket.AF_INET, '1.1.1.0'), src_prefix_len = 24,
                                         dst_ip = socket.inet_pton(socket.AF_INET, '8.8.8.0'), dst_prefix_len = 24,
                                         seq_num = 100)
    assert rid1 is not None
    rid2 = cfg.process_vrf_svcs_rule_add(cfg.VrfSvcsRuleType.RULE_TYPE_ACL, 'test_management',
                                         cfg.VrfSvcsRuleAction.RULE_ACTION_ALLOW,
                                         socket.AF_INET6,
                                         src_ip = socket.inet_pton(socket.AF_INET6, '1:1::'), src_prefix_len = 64,
                                         dst_ip = socket.inet_pton(socket.AF_INET6, '2:2::'), dst_prefix_len = 64,
                                         seq_num = 101)
    assert rid2 is not None
    rid3 = cfg.process_vrf_svcs_rule_add(cfg.VrfSvcsRuleType.RULE_TYPE_IP, 'test_management',
                                         cfg.VrfSvcsRuleAction.RULE_ACTION_DNAT,
                                         socket.AF_INET,
                                         protocol = cfg.VrfSvcsRuleProto.RULE_PROTO_TCP, dst_port = 1234,
                                         dst_ip = socket.inet_pton(socket.AF_INET, '3.3.3.3'))
    assert rid3 is not None
    rid4 = cfg.process_vrf_svcs_rule_add(cfg.VrfSvcsRuleType.RULE_TYPE_IP, 'test_management',
                                         cfg.VrfSvcsRuleAction.RULE_ACTION_DNAT,
                                         socket.AF_INET6,
                                         protocol = cfg.VrfSvcsRuleProto.RULE_PROTO_TCP, dst_port = 1235,
                                         dst_ip = socket.inet_pton(socket.AF_INET6, '3::3'))
    assert rid4 is not None

    assert cfg.process_vrf_svcs_rule_set(rid1, src_ip = socket.inet_pton(socket.AF_INET, '2.2.2.0'))
    assert cfg.process_vrf_svcs_rule_set(rid2, seq_num = 200)
    assert not cfg.process_vrf_svcs_rule_del(cfg.VrfSvcsRuleType.RULE_TYPE_ACL, 'test_management',
                                             cfg.VrfSvcsRuleAction.RULE_ACTION_DENY, socket.AF_INET,
                                             src_ip = socket.inet_pton(socket.AF_INET, '1.1.1.0'), src_prefix_len = 24)
    assert cfg.process_vrf_svcs_rule_del(cfg.VrfSvcsRuleType.RULE_TYPE_ACL, 'test_management',
                                         cfg.VrfSvcsRuleAction.RULE_ACTION_DENY, socket.AF_INET,
                                         src_ip = socket.inet_pton(socket.AF_INET, '2.2.2.0'), src_prefix_len = 24,
                                         dst_ip = socket.inet_pton(socket.AF_INET, '8.8.8.0'), dst_prefix_len = 24)
    assert not cfg.process_vrf_svcs_rule_del_by_id(rid1)
    assert cfg.process_vrf_svcs_rule_del_by_id(rid2)
    resp = []
    assert cfg.process_vrf_svcs_rule_get(resp)
    assert len(resp) == 2
    assert cfg.process_vrf_svcs_rule_del_by_id(rid3)
    assert cfg.process_vrf_svcs_rule_del_by_id(rid4)
コード例 #3
0
def create_default_lo_pkts_rule():
    loopback_ip_str = '127.0.0.1'
    loopback_intf = 'lo'

    rule_id = process_vrf_svcs_rule_add(
        VrfSvcsRuleType.RULE_TYPE_IP,
        'default',
        VrfSvcsRuleAction.RULE_ACTION_ALLOW,
        socket.AF_INET,
        src_ip=socket.inet_pton(socket.AF_INET, loopback_ip_str),
        src_prefix_len=32,
        dst_ip=socket.inet_pton(socket.AF_INET, loopback_ip_str),
        dst_prefix_len=32,
        high_prio=True,
        in_intf=loopback_intf)
    if rule_id is None:
        log_err('Failed to create default rule to accept pkts on lo')
        return (False, rule_id)
    return (True, rule_id)
コード例 #4
0
def create_vrf_default_rules(vrf_name, rule_id_list=None):
    for af in [socket.AF_INET, socket.AF_INET6]:
        any_ip_str = '0.0.0.0' if af == socket.AF_INET else '::'
        intf = 'vdst-nsid+'
        rule_id = process_vrf_svcs_rule_add(
            VrfSvcsRuleType.RULE_TYPE_ACL,
            vrf_name,
            VrfSvcsRuleAction.RULE_ACTION_ALLOW,
            af,
            src_ip=socket.inet_pton(af, any_ip_str),
            src_prefix_len=0,
            high_prio=True,
            in_intf=intf)
        if rule_id is None:
            log_err(
                'Failed to create default ACL rules: VRF %s af %d intf %s' %
                (vrf_name, af, intf))
            return False
        if rule_id_list is not None:
            log_info('Default rule created: VRF %s af %d intf %s ID %d' %
                     (vrf_name, af, intf, rule_id))
            rule_id_list.append(rule_id)
    return True
コード例 #5
0
def config_incoming_ip_svcs_int(methods, params):
    obj = cps_object.CPSObject(obj=params['change'])
    in_param_list = {}

    log_info('Callback for incoming IP service configuration')

    def get_svcs_attr_val(attr_name, dft_val=None):
        attr_id = incoming_ip_svcs_attr(attr_name)
        try:
            attr_val = obj.get_attr_data(attr_id)
        except ValueError:
            attr_val = None
        if attr_val is None:
            attr_val = dft_val
        in_param_list[attr_name] = attr_val
        return attr_val

    operation = params['operation']

    af = get_svcs_attr_val('af')
    vrf_name = get_svcs_attr_val('ni-name')
    protocol = get_svcs_attr_val('protocol')
    dst_port = get_svcs_attr_val('dst-port')
    low_dst_port = get_svcs_attr_val('lower-dst-port')
    high_dst_port = get_svcs_attr_val('upper-dst-port')
    action = get_svcs_attr_val('action')
    src_ip = get_svcs_attr_val('src-ip')
    src_prefix_len = get_svcs_attr_val('src-prefix-len')
    dst_ip = get_svcs_attr_val('dst-ip')
    dst_prefix_len = get_svcs_attr_val('dst-prefix-len')
    in_intf = get_svcs_attr_val('ifname')
    if operation == 'create':
        # set default seq number to 0 for create
        seq_num = get_svcs_attr_val('seq-num', 0)
    else:
        seq_num = get_svcs_attr_val('seq-num')
    rule_id = get_svcs_attr_val('id')

    # check source and destination IP
    if src_ip is not None:
        ip_tuple = normalize_ip_with_prefix(af, src_ip, src_prefix_len)
        if ip_tuple is None:
            log_err('Failed to normalize source IP with prefix')
            return False
        orig_af = af
        af, src_ip, src_prefix_len = ip_tuple
        if orig_af is None:
            log_info('Address family %d is deduced from input source IP %s' %
                     (af, src_ip))
        in_param_list['af'] = af
        in_param_list['src-ip'] = src_ip
        in_param_list['src-prefix-len'] = src_prefix_len
    if dst_ip is not None:
        ip_tuple = normalize_ip_with_prefix(af, dst_ip, dst_prefix_len)
        if ip_tuple is None:
            log_err('Failed to normalize destination IP with prefix')
            return False
        orig_af = af
        af, dst_ip, dst_prefix_len = ip_tuple
        if orig_af is None:
            log_info(
                'Address family %d is deduced from input destination IP %s' %
                (af, dst_ip))
        in_param_list['af'] = af
        in_param_list['dst-ip'] = dst_ip
        in_param_list['dst-prefix-len'] = dst_prefix_len

    # check lower & upper destination ports
    if low_dst_port is not None and high_dst_port is None:
        log_err('Missing upper-dst-port for VTY ACL rule configuration')
        return False
    if low_dst_port is None and high_dst_port is not None:
        log_err('Missing lower-dst-port for VTY ACL rule configuration')
        return False
    if (low_dst_port is not None
            or high_dst_port is not None) and dst_port is not None:
        log_err('Invalid VTY ACL rule configuration, \
                 dst port attribute cannot be configured along with dst port range attributes'
                )
        return False
    """
    The input object stands for VTY ACL configuration request if:
    1. Destination L4 port attribute is not given or given value is 0,
    2. Or Source IP address attribute is given,
    3. Or lower & upper destination L4 port attributes are given.

    For all other cases, input object stands for VRF incoming IP service
    request.
    """

    def is_vty_acl_config():
        if dst_port is None or dst_port == 0:
            return True
        if src_ip is not None:
            return True
        if low_dst_port is not None and high_dst_port is not None:
            return True
        return False

    log_info('Input parameters:')
    for name, val in in_param_list.items():
        if val is not None:
            if name == 'src-ip' or name == 'dst-ip':
                log_info('  %-10s - %s' % (name, binascii.hexlify(val)))
            else:
                log_info('  %-10s - %s' % (name, str(val)))

    if is_vty_acl_config():
        log_info('Handle VTY ACL configuration, operation: %s' % operation)
        rule_type = VrfSvcsRuleType.RULE_TYPE_ACL
        reqd_input = ['ni-name', 'af', 'src-ip', 'src-prefix-len', 'action']
    else:
        log_info('Handle incoming IP configuration, operation: %s' % operation)
        rule_type = VrfSvcsRuleType.RULE_TYPE_IP
        reqd_input = ['af', 'ni-name', 'protocol', 'dst-port']
        if vrf_name == 'default':
            reqd_input.append('action')

    def check_rule_input(missed_attr_list=None):
        """ The keys to identify a rule """
        if operation == 'delete':
            """
            For delete operation, either rule ID or rule keys need to be given to find
            rule to be deleted
            """
            if rule_id is not None:
                return True
            else:
                if check_attr_list(reqd_input, in_param_list,
                                   missed_attr_list):
                    return True
        elif operation == 'set':
            """
            For set operation, rule ID is the only required input to find the rule to be
            updated. And the attributes of the rule will be changed to attribute value
            given by input
            """
            if rule_id is not None:
                return True
            else:
                if missed_attr_list is not None:
                    missed_attr_list.append('id')
        elif operation == 'create':
            """
            For create operation, all key attributes plus sequence number need to be given
            by input
            """
            if check_attr_list(reqd_input + ['seq-num'], in_param_list,
                               missed_attr_list):
                return True

        return False

    not_found_list = []
    if not check_rule_input(not_found_list):
        log_err('Mandatory attributes %s not found for operation %s' %
                (str(not_found_list), operation))
        return False

    if operation == 'create':
        if rule_type == VrfSvcsRuleType.RULE_TYPE_IP and vrf_name != 'default':
            """
            If it is IP forwarding rule and the name space is not default, we set its action
            type as DNAT
            """
            dst_ip = dn_base_vrf_tool.get_veth_ip(af, vrf_name)
            action = VrfSvcsRuleAction.RULE_ACTION_DNAT
        else:
            if (dst_port is not None
                    and protocol != VrfSvcsRuleProto.RULE_PROTO_TCP
                    and protocol != VrfSvcsRuleProto.RULE_PROTO_UDP):
                log_err(
                    'L4 destination port filter must with protocol type TCP or UDP'
                )
                return False
            if (low_dst_port is not None
                    and protocol != VrfSvcsRuleProto.RULE_PROTO_TCP
                    and protocol != VrfSvcsRuleProto.RULE_PROTO_UDP):
                log_err(
                    'L4 destination port range filter must with protocol type TCP or UDP'
                )
                return False
        ret_val = process_vrf_svcs_rule_add(rule_type,
                                            vrf_name,
                                            action,
                                            af,
                                            src_ip=src_ip,
                                            src_prefix_len=src_prefix_len,
                                            dst_ip=dst_ip,
                                            dst_prefix_len=dst_prefix_len,
                                            seq_num=seq_num,
                                            protocol=protocol,
                                            dst_port=dst_port,
                                            low_dst_port=low_dst_port,
                                            high_dst_port=high_dst_port,
                                            in_intf=in_intf,
                                            rule_id=rule_id)
        if ret_val is None:
            log_err(
                'Failed to add incoming IP rule: VRF %s AF %s%s%s%s%s%s%s%s%s%s%s'
                % (vrf_name, _af[af],
                   (' IIF %s' % in_intf if in_intf is not None else ' '),
                   (' SRC %s/%d' % (get_ip_str(af, src_ip), src_prefix_len) if
                    src_ip is not None and src_prefix_len is not None else ''),
                   (' DST %s/%d' % (get_ip_str(af, dst_ip), dst_prefix_len) if
                    dst_ip is not None and dst_prefix_len is not None else ''),
                   (' PROTO %s' %
                    _protocol[protocol] if protocol is not None else ''),
                   (' PORT %d' % dst_port if dst_port is not None else ''),
                   (' PORT RANGE %d-%d' % (low_dst_port, high_dst_port)
                    if low_dst_port is not None else ''),
                   (' SEQ %d' % seq_num if seq_num is not None else ''),
                   (' ACTION %s' %
                    _action[action] if action is not None else ''),
                   (' DST %s' %
                    get_ip_str(af, dst_ip) if dst_ip is not None else ''),
                   (' ID %d' % rule_id if rule_id is not None else '')))
            return False
        if rule_id is not None and ret_val != rule_id:
            log_err('Given rule id %d is not equal to actually used id %d' %
                    (rule_id, ret_val))
        obj.add_attr(incoming_ip_svcs_attr('id'), ret_val)
        params['change'] = obj.get()
    elif operation == 'set':
        ret_val = process_vrf_svcs_rule_set(rule_id,
                                            src_ip=src_ip,
                                            src_prefix_len=src_prefix_len,
                                            protocol=protocol,
                                            dst_ip=dst_ip,
                                            dst_prefix_len=dst_prefix_len,
                                            dst_port=dst_port,
                                            action=action,
                                            low_dst_port=low_dst_port,
                                            high_dst_port=high_dst_port,
                                            seq_num=seq_num,
                                            in_intf=in_intf)
        if not ret_val:
            log_err('Failed to update rule with ID %d' % rule_id)
            return False
    elif operation == 'delete':
        if rule_id is None:
            if rule_type == VrfSvcsRuleType.RULE_TYPE_IP and vrf_name != 'default':
                """
                If it is IP forwarding rule and the name space is not default, we set its action
                type as DNAT
                """
                dst_ip = dn_base_vrf_tool.get_veth_ip(af, vrf_name)
                action = VrfSvcsRuleAction.RULE_ACTION_DNAT
            ret_val = process_vrf_svcs_rule_del(rule_type,
                                                vrf_name,
                                                action,
                                                af,
                                                src_ip=src_ip,
                                                src_prefix_len=src_prefix_len,
                                                dst_ip=dst_ip,
                                                dst_prefix_len=dst_prefix_len,
                                                protocol=protocol,
                                                dst_port=dst_port,
                                                low_dst_port=low_dst_port,
                                                high_dst_port=high_dst_port,
                                                in_intf=in_intf)
        else:
            ret_val = process_vrf_svcs_rule_del_by_id(rule_id)
        if not ret_val:
            log_err('Failed to delete rule')
            return False
    else:
        log_err('Invalid operation type %s' % operation)
        return False

    return True
コード例 #6
0
def config_incoming_ip_svcs_int(methods, params):
    obj = cps_object.CPSObject(obj=params['change'])
    in_param_list = {}

    log_info('Callback for incoming IP service configuration')

    def get_svcs_attr_val(attr_name, dft_val=None):
        attr_id = incoming_ip_svcs_attr(attr_name)
        try:
            attr_val = obj.get_attr_data(attr_id)
        except ValueError:
            attr_val = None
        if attr_val is None:
            attr_val = dft_val
        in_param_list[attr_name] = attr_val
        return attr_val

    operation = params['operation']

    af = get_svcs_attr_val('af')
    vrf_name = get_svcs_attr_val('ni-name')
    protocol = get_svcs_attr_val('protocol')
    dst_port = get_svcs_attr_val('dst-port')
    action = get_svcs_attr_val('action')
    src_ip = get_svcs_attr_val('src-ip')
    prefix_len = get_svcs_attr_val('src-prefix-len')
    if operation == 'create':
        # set default seq number to 0 for create
        seq_num = get_svcs_attr_val('seq-num', 0)
    else:
        seq_num = get_svcs_attr_val('seq-num')
    rule_id = get_svcs_attr_val('id')

    # check source IP
    if src_ip is not None:
        af_ip = check_ip_validity(af, src_ip)
        if af_ip is None:
            log_err('Invalid source IP %s for rule configuration' % src_ip)
            return False
        orig_af = af
        af, src_ip = af_ip
        if orig_af is None:
            log_info('Address family %d is deducted from input source IP %s' %
                     (af, src_ip))
            in_param_list['af'] = af
        in_param_list['src-ip'] = src_ip

        # set default prefix len
        if prefix_len is None and af is not None:
            if af == socket.AF_INET:
                prefix_len = 32
            elif af == socket.AF_INET6:
                prefix_len = 128
            in_param_list['src-prefix-len'] = prefix_len
    """
    The input object stands for VTY ACL configuration request if:
    1. Destination L4 port attribute is not given or given value is 0.
    2. Or Source IP address attribute is given

    For all other cases, input object stands for VRF incoming IP service
    request.
    """

    def is_vty_acl_config():
        if dst_port is None or dst_port == 0:
            return True
        if src_ip is not None:
            return True
        return False

    def check_attr_list(attr_list, missed_list=None):
        ret_val = True
        for attr in attr_list:
            if attr not in in_param_list or in_param_list[attr] is None:
                ret_val = False
                if missed_list is not None:
                    missed_list.append(attr)
        return ret_val

    def get_ip_str(ip_bin):
        for af in [socket.AF_INET, socket.AF_INET6]:
            try:
                ip_str = socket.inet_ntop(af, ip_bin)
                return ip_str
            except ValueError:
                continue
        return '-'

    log_info('Input parameters:')
    for name, val in in_param_list.items():
        if val is not None:
            if name == 'src-ip':
                log_info('  %-10s - %s' % (name, binascii.hexlify(val)))
            else:
                log_info('  %-10s - %s' % (name, str(val)))

    if is_vty_acl_config():
        log_info('Handle VTY ACL configuration, operation: %s' % operation)
        rule_type = VrfIncomingSvcsRule.RULE_TYPE_ACL
        reqd_input = ['ni-name', 'af', 'src-ip', 'src-prefix-len', 'action']
    else:
        log_info('Handle incoming IP configuration, operation: %s' % operation)
        rule_type = VrfIncomingSvcsRule.RULE_TYPE_IP
        reqd_input = ['af', 'ni-name', 'protocol', 'dst-port']
        if vrf_name == 'default':
            reqd_input.append('action')

    def check_rule_input(missed_attr_list=None):
        """ The keys to identify a rule """
        if operation == 'delete':
            """
            For delete operation, either rule ID or rule keys need to be given to find
            rule to be deleted
            """
            if rule_id is not None:
                return True
            else:
                if check_attr_list(reqd_input, missed_attr_list):
                    return True
        elif operation == 'set':
            """
            For set operation, rule ID is the only required input to find the rule to be
            updated. And the attributes of the rule will be changed to attribute value
            given by input
            """
            if rule_id is not None:
                return True
            else:
                if missed_attr_list is not None:
                    missed_attr_list.append('id')
        elif operation == 'create':
            """
            For create operation, all key attributes plus sequence number need to be given
            by input
            """
            if check_attr_list(reqd_input + ['seq-num'], missed_attr_list):
                return True

        return False

    not_found_list = []
    if not check_rule_input(not_found_list):
        log_err('Mandatory attributes %s not found for operation %s' %
                (str(not_found_list), operation))
        return False

    if operation == 'create':
        if rule_type == VrfIncomingSvcsRule.RULE_TYPE_IP and vrf_name != 'default':
            """
            If it is IP forwarding rule and the name space is not default, we set its action
            type as DNAT
            """
            dst_ip = dn_base_vrf_tool.get_veth_ip(af, vrf_name)
            action = VrfIncomingSvcsRule.RULE_ACTION_DNAT
        else:
            if (dst_port is not None
                    and protocol != VrfIncomingSvcsRule.RULE_PROTO_TCP
                    and protocol != VrfIncomingSvcsRule.RULE_PROTO_UDP):
                log_err(
                    'L4 destination port filter must with protocol type TCP or UDP'
                )
                return False
            dst_ip = None
        ret_val = process_vrf_svcs_rule_add(rule_type,
                                            vrf_name,
                                            action,
                                            af,
                                            src_ip=src_ip,
                                            prefix_len=prefix_len,
                                            dst_ip=dst_ip,
                                            seq_num=seq_num,
                                            protocol=protocol,
                                            dst_port=dst_port,
                                            rule_id=rule_id)
        if ret_val is None:
            log_err(
                'Failed to add incoming IP rule: VRF %s AF %s%s%s%s%s%s%s%s' %
                (vrf_name, _af[af],
                 (' SRC %s/%d' % (get_ip_str(src_ip), prefix_len)
                  if src_ip is not None and prefix_len is not None else ''),
                 (' PROTO %s' %
                  _protocol[protocol] if protocol is not None else ''),
                 (' PORT %d' % dst_port if dst_port is not None else ''),
                 (' SEQ %d' % seq_num if seq_num is not None else ''),
                 (' ACTION %s' %
                  _action[action] if action is not None else ''),
                 (' DST %s' %
                  get_ip_str(dst_ip) if dst_ip is not None else ''),
                 (' ID %d' % rule_id if rule_id is not None else '')))
            return False
        if rule_id is not None and ret_val != rule_id:
            log_err('Given rule id %d is not equal to actually used id %d' %
                    (rule_id, ret_val))
        obj.add_attr(incoming_ip_svcs_attr('id'), ret_val)
        params['change'] = obj.get()
    elif operation == 'set':
        ret_val = process_vrf_svcs_rule_set(rule_id,
                                            src_ip=src_ip,
                                            prefix_len=prefix_len,
                                            protocol=protocol,
                                            dst_port=dst_port,
                                            action=action,
                                            seq_num=seq_num)
        if not ret_val:
            log_err('Failed to update rule with ID %d' % rule_id)
            return False
    elif operation == 'delete':
        if rule_id is None:
            if rule_type == VrfIncomingSvcsRule.RULE_TYPE_IP and vrf_name != 'default':
                """
                If it is IP forwarding rule and the name space is not default, we set its action
                type as DNAT
                """
                dst_ip = dn_base_vrf_tool.get_veth_ip(af, vrf_name)
                action = VrfIncomingSvcsRule.RULE_ACTION_DNAT
            else:
                dst_ip = None
            ret_val = process_vrf_svcs_rule_del(rule_type,
                                                vrf_name,
                                                action,
                                                af,
                                                src_ip=src_ip,
                                                prefix_len=prefix_len,
                                                dst_ip=dst_ip,
                                                protocol=protocol,
                                                dst_port=dst_port)
        else:
            ret_val = process_vrf_svcs_rule_del_by_id(rule_id)
        if not ret_val:
            log_err('Failed to delete rule')
            return False
    else:
        log_err('Invalid operation type %s' % operation)
        return False

    return True