MPM context explanation

Hi there!

I am doing a thesis about Suriacat implementation. I´m having a hard time trying to figure it out what is, exactly, the mpm-context.

Can someone please explain me?

Hi Nuno!

This is a late reply, but I’m posting it in case because it might still be useful for you, and, if not, it could be the answer to someone else’s questions, in the future. (I ask you to forgive me beforehand if I’m going into concepts that may be too basic to you. One never knows in advance.)

So, MPM stands for multiple-pattern-matcher, and is part of the detection engine in Suricata. That means that it is used as part of the process of analyzing incoming packets against the registered rules Suricata is working with.

A rule/signature has one or more patterns. For a rule to be triggered, all patterns in that signature must match. The MPM will select a pattern from each signature, and use that collection to analyze packets. If a packet matches against the MPM, then further analysis is done. More about how MPM works can be found in our user documentation: 10.1. Suricata.yaml — Suricata 7.0.0-dev documentation

MPM-Context is also important for perfomance reasons. The MPM uses patterns from several rules (in a predefined signature group, from my understanding). Now, some rule groups need shared context, while others may need independent contexts.

From the suricata.yaml file:

# The detection engine builds internal groups of signatures. The engine
# allows us to specify the profile to use for them, to manage memory in an
# efficient way keeping good performance. For the profile keyword you
# can use the words "low", "medium", "high" or "custom". If you use custom,
# make sure to define the values in the "custom-values" section.
# Usually you would prefer medium/high/low.
#
# "sgh mpm-context", indicates how the staging should allot mpm contexts for
# the signature groups.  "single" indicates the use of a single context for
# all the signature group heads.  "full" indicates a mpm-context for each
# group head.  "auto" lets the engine decide the distribution of contexts
# based on the information the engine gathers on the patterns from each
# group head.

The MPM-context works together with the MPM-algorithm used (mpm-algo) as explained in Tuning considerations(9.3. Tuning Considerations — Suricata 7.0.0-dev documentation). If auto is chosen, the engine will select between having the context per signature group (full), or globally (single). When in doubt, this is likely the better alternative, for the average user.

I hope this can be of any help, and good luck with your thesis :slight_smile:

Sorry for the late reply (and maybe for my ignorance).

What i´m finding myself in trouble to understand is what the “context” specifically means. It is like an identifier of the common patterns in a rule group?

Hello again!

No one is born knowing, and I myself am still learning many of Suri’s ways :slight_smile: I had to do more digging to try to find a better answer to your question.

So, in that same section of Suri documentation, 10.1. Suricata.yaml — Suricata 7.0.0-dev documentation, there’s a paragraph referring to the mpm-context also as the settings for the multi-pattern matching algorithm itself - adding that each Signature Head Group ( sgh - each group of signatures that share some common characteristics) has its own mpm-context. Said context can be defined as global (single in the configuration) or non-global (full).

But that still doesn’t say a lot. Checking detect-engine-mpm.c and following from there, I got to util-mpm.h There, mpm-context is declared as a struct that stores configurations related to and used by the pattern matching algorithm. Then, in In util-mpm.c, in the MpmAddPattern function, there’s a comment (quoted before the code snippet below) that explains that for single context, the same mpm_ctx might be called several times, for the same signature id, since multiple sgh can be adding the same pattern to the shared context. In the same file, in the function MpmFactoryGetMpmCtxForProfile, we can see that if Suricata sees that the profile id is MPM_CTX_FACTORY_UNIQUE_CONTEXT it allocates memory space for a MpmCtx and returns it, instead of checking in the factory container for other mpm-contexts.

So the mpm-context represents a few things in Suri. First, if said context will be shared between signature groups, and, then, the details of the context itself, like type of algorithm, pattern count, and max pattern id.

I hope this may be useful to clarify a bit further what the mpm-context is/means!

From util-mpm.h:

/* Indicates if this a global mpm_ctx.  Global mpm_ctx is the one that
 * is instantiated when we use "single".  Non-global is "full", i.e.
 * one per sgh. */
#define MPMCTX_FLAGS_GLOBAL     BIT_U8(0)
#define MPMCTX_FLAGS_NODEPTH    BIT_U8(1)

typedef struct MpmCtx_ {
    void *ctx;
    uint8_t mpm_type;

    uint8_t flags;

    uint16_t maxdepth;

    /* unique patterns */
    uint32_t pattern_cnt;

    uint16_t minlen;
    uint16_t maxlen;

    uint32_t memory_cnt;
    uint32_t memory_size;

    uint32_t max_pat_id;

    /* hash used during ctx initialization */
    MpmPattern **init_hash;
} MpmCtx;

From util-mpm.c in MpmAddPattern function:

/* we can be called multiple times for the same sid in the case
 * of the 'single' modus. Here multiple rule groups share the
 * same mpm ctx and might be adding the same pattern to the
 * mpm_ctx */