# Call / Macro Statements

## call

Instantiate a macro within the current namespace. There may be zero or more parameters passed to the macro (with zero parameters this is similar to the `blockinherit` (`call`) / `blockabstract` (`macro`) statements).

Each parameter passed contains an argument to be resolved by the macro, these can be named or anonymous but must conform to the parameter types defined in the `macro` statement.

Statement definition:

    (call macro_id [(param ...)])

Where:

`call` | The `call` keyword.
`macro_id` | The identifier of the `macro` to be instantiated.
`param` | Zero or more parameters that are passed to the macro.

Example:

See the `macro` statement for an example.

## macro

Declare a macro in the current namespace with its associated parameters. The macro identifier is used by the `call` statement to instantiate the macro and resolve any parameters. The call statement may be within the body of a macro.

Note that when resolving macros the callers namespace is not checked, only the following places:

- Items defined inside the macro

- Items passed into the macro as arguments

- Items defined in the same namespace of the macro

- Items defined in the global namespace

Statement definition:

    (macro macro_id ([(param_type param_id) ...])
        cil_statements
        ...
    )

Where:

`macro` | The `macro` keyword.
`macro_id` | The `macro` identifier.
`param_type` | Zero or more parameters that are passed to the macro. The `param_type` is a keyword used to determine the declaration type (e.g. `type`, `class`, `categoryset`). The list of valid `param_type` entries are: `type` `typealias` `role` `user` `sensitivity` `sensitivityalias` `category` `categoryalias` `categoryset` (named or anonymous) `level` (named or anonymous) `levelrange` (named or anonymous) `class` `classpermission` (named or anonymous) `ipaddr` (named or anonymous) `block` `name` (a string) `classmap`
`param_id` | The parameter identifier used to reference the entry within the macro body (e.g. `ARG1`).
`cil_statement` | Zero or more valid CIL statements.

Examples:

This example will instantiate the `binder_call` macro in the calling namespace (`my_domain`) and replace `ARG1` with `appdomain` and `ARG2` with `binderservicedomain`:

    (block my_domain
        (call binder_call (appdomain binderservicedomain))
    )

    (macro binder_call ((type ARG1) (type ARG2))
        (allow ARG1 ARG2 (binder (call transfer)))
        (allow ARG2 ARG1 (binder (transfer)))
        (allow ARG1 ARG2 (fd (use)))
    )

This example does not pass any parameters to the macro but adds a `type` identifier to the current namespace:

    (block unconfined
        (call add_type)
        ....

        (macro add_type ()
            (type exec)
        )
    )

This example passes an anonymous and named IP address to the macro:

    (ipaddr netmask_1 255.255.255.0)
    (context netlabel_1 (system.user object_r unconfined.object low_low)

    (call build_nodecon ((192.168.1.64) netmask_1))

    (macro build_nodecon ((ipaddr ARG1) (ipaddr ARG2))
        (nodecon ARG1 ARG2  netlabel_1)
    )