summaryrefslogtreecommitdiff
path: root/cesar/cl/src/cl_mactotei.c
blob: 391919a449603bd323b40af979fc721b6fba64e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    cl/src/cl_mactotei.c
 * \brief   MAC to TEI table interface between the CL and the CP.
 * \ingroup cl
 */
#include "common/std.h"
#include "cl/cl_mactotei.h"

#include "cl/inc/cl.h"
#include "mac/common/defs.h"
#include "mac/common/ntb.h"

/**
 * Set a TEI and a tag in an extra information field.
 * \param  tei  TEI to set.
 * \param  tag  Tag to set.
 * \return  The extra information value with the TEI and tag set correctly.
 */
static inline u16
cl_mactotei_set_tei_tag (uint tei, uint tag)
{
    /* Check parameters. */
    dbg_assert (MAC_TEI_IS_STA (tei));
    dbg_assert (tag <= 0xFF);
    u16 extra_info = 0;
    extra_info = tei;
    extra_info <<= 8;
    extra_info |= tag;
    return extra_info;
}

/**
 * Internal release of a MAC to TEI table.
 * \param  mactotei_table  MAC to TEI table to release.
 *
 * This function supports to have a NULL mactotei_table (in this case, it does
 * nothing). It can be used to do an atomic release of the MAC to TEI table.
 * The differences with the cl_mactotei_release_table function are:
 *  - it does not depend on the CL context, it only needs a
 *  cl_mactotei_table_t,
 *  - this function is private.
 */
static inline void
cl_mactotei_release_table_internal (cl_mactotei_table_t *mactotei_table)
{
    /* If there is a table to release. */
    if (mactotei_table)
    {
        /* Release. */
        mac_lookup_table_release (mactotei_table);
    }
}

cl_mactotei_blk_t *
cl_mactotei_new (void)
{
    return mac_lookup_table_create ();
}

void
cl_mactotei_copy_tei_and_tag (cl_t *ctx, cl_mactotei_blk_t *table,
                              uint tei, uint tag)
{
    /* Check parameters. */
    dbg_assert (ctx);

    cl_mactotei_table_t *table_old = ctx->mactotei;
    /* Nothing to copy. */
    if (table_old == NULL)
        return;

    /* Copy entries with matching TEI and tag. */
    mac_lookup_table_copy (table_old, table, 0xFFFF,
                           cl_mactotei_set_tei_tag (tei, tag));
}

void
cl_mactotei_addr_add (cl_mactotei_blk_t *table, mac_t mac_addr,
                      uint tei, uint tag)
{
    /* No need to check parameters, they are not directly used by this
     * function. */
    /* Add MAC address and extra information associated to the table. */
    mac_lookup_table_add_entry (table, mac_addr,
                                cl_mactotei_set_tei_tag (tei, tag));
}

void
cl_mactotei_release_table (cl_t *ctx)
{
    /* Check parameters. */
    dbg_assert (ctx);

    /* Copy the MAC to TEI table into a temporary one. */
    cl_mactotei_table_t *tmp = ctx->mactotei;
    /* Atomic release. */
    ctx->mactotei = NULL;
    /* Do the real release. */
    cl_mactotei_release_table_internal (tmp);
    /* Clear data_send_link cache. */
    cl_data_send_link_clear (ctx);
}

void
cl_mactotei_use_table (cl_t *ctx, cl_mactotei_blk_t *table)
{
    /* Check parameter that need it. */
    dbg_assert (ctx);

    /* Copy the MAC to TEI table into a temporary one. */
    cl_mactotei_table_t *tmp = ctx->mactotei;
    /* Atomic set up new table. */
    ctx->mactotei = mac_lookup_table_convert (table);
    /* Do the real release of previous table. */
    cl_mactotei_release_table_internal (tmp);
    /* Clear data_send_link cache. */
    cl_data_send_link_clear (ctx);
}

uint
cl_mactotei_table_find_tei_from_mac (cl_t *ctx, mac_t mac)
{
    /* Check parameter. */
    dbg_assert (ctx);

    /* Empty MAC to TEI table? */
    if (ctx->mactotei)
    {
        u16 extra_info;
        /* Entry exist? */
        if (mac_lookup_table_find_entry (ctx->mactotei, mac, &extra_info))
        {
            CL_TRACE (MACTOTEI_FIND_TEI, mac_ntb(), TRACE_U64(mac), true,
                      extra_info >> 8);
            return extra_info >> 8;
        }
    }

    /* Entry does not exist. */
    CL_TRACE (MACTOTEI_FIND_TEI, mac_ntb(), TRACE_U64(mac), false,
              MAC_TEI_UNASSOCIATED);
    return MAC_TEI_UNASSOCIATED;
}

void
cl_mactotei_copy_except_tag (cl_t *ctx, cl_mactotei_blk_t *table, uint tag)
{
    /* Check parameters. */
    dbg_assert (ctx);

    cl_mactotei_table_t *table_old = ctx->mactotei;
    /* Nothing to copy. */
    if (table_old == NULL)
        return;

    /* Copy entries with matching TEI and tag. */
    mac_lookup_table_copy_except (table_old, table, 0x00FF, tag);
}

void
cl_mactotei_cancel (cl_mactotei_blk_t *table)
{
    /* Release table from memory. */
    mac_lookup_table_delete (table);
}