Typos. A bunch of typos I've been collecting.
[vpp.git] / src / vnet / bier / bier_fmask_db.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/bier/bier_fmask_db.h>
17 #include <vnet/bier/bier_fmask.h>
18
19 /**
20  * Global Table of fmask objects
21  * The key into this table includes the table's key and the fmask's key,
22  * so there could be a DB per-table. But it is more efficient
23  * at forwarding time to extract the fmask from a single global table
24  * which is hot in dcache.
25  *
26  * The table's key is part of this DB key, since the fmasks therein build up
27  * their forwarding mask based on the routes that resolve through
28  * it, so cross pollination would be bad.
29  */
30 typedef struct bier_fmask_db_t_ {
31     /**
32      * hash table for underlying storage
33      */
34     uword *bfdb_hash;
35
36     /**
37      * Pool for memory
38      */
39     struct bier_fmask_t_ *bfdb_pool;
40 } bier_fmask_db_t;
41
42 /**
43  * Single fmask DB
44  */
45 static bier_fmask_db_t bier_fmask_db;
46
47
48 u32
49 bier_fmask_get_index (const bier_fmask_t *bfm)
50 {
51     return (bfm - bier_fmask_db.bfdb_pool);
52 }
53
54 static void
55 bier_fmask_db_mk_key (index_t bti,
56                       const fib_route_path_t *rpath,
57                       bier_fmask_id_t *key)
58 {
59     /*
60      * Depending on what the ID is there may be padding.
61      * This key will be memcmp'd in the mhash, so make sure it's all 0
62      */
63     clib_memset(key, 0, sizeof(*key));
64
65     /*
66      * Pick the attributes from the path that make the FMask unique
67      */
68     if (FIB_ROUTE_PATH_UDP_ENCAP & rpath->frp_flags)
69     {
70         key->bfmi_id = rpath->frp_udp_encap_id;
71         key->bfmi_nh_type = BIER_NH_UDP;
72     }
73     else
74     {
75         memcpy(&key->bfmi_nh, &rpath->frp_addr, sizeof(rpath->frp_addr));
76         key->bfmi_nh_type = BIER_NH_IP;
77     }
78     if (NULL == rpath->frp_label_stack)
79     {
80         key->bfmi_hdr_type = BIER_HDR_O_OTHER;
81     }
82     else
83     {
84         key->bfmi_hdr_type = BIER_HDR_O_MPLS;
85     }
86     key->bfmi_bti = bti;
87 }
88
89 u32
90 bier_fmask_db_find (index_t bti,
91                     const fib_route_path_t *rpath)
92 {
93     bier_fmask_id_t fmid;
94     uword *p;
95
96     bier_fmask_db_mk_key(bti, rpath, &fmid);
97     p = hash_get_mem(bier_fmask_db.bfdb_hash, &fmid);
98
99     if (NULL != p)
100     {
101         return (p[0]);
102     }
103
104     return (INDEX_INVALID);
105 }
106
107 u32
108 bier_fmask_db_find_or_create_and_lock (index_t bti,
109                                        const fib_route_path_t *rpath)
110 {
111     bier_fmask_id_t fmid;
112     u32 index;
113     uword *p;
114
115     bier_fmask_db_mk_key(bti, rpath, &fmid);
116     p = hash_get_mem(bier_fmask_db.bfdb_hash, &fmid);
117
118     if (NULL == p)
119     {
120         bier_fmask_t *bfm;
121         /*
122          * adding a new fmask object
123          */
124         index = bier_fmask_create_and_lock(&fmid, rpath);
125         bfm = bier_fmask_get(index);
126         hash_set_mem(bier_fmask_db.bfdb_hash, bfm->bfm_id, index);
127     }
128     else
129     {
130         index = p[0];
131         bier_fmask_lock(index);
132     }
133
134     return (index);
135 }
136
137 void
138 bier_fmask_db_remove (const bier_fmask_id_t *fmid)
139 {
140     uword *p;
141
142     p = hash_get_mem(bier_fmask_db.bfdb_hash, fmid);
143
144     if (NULL == p) {
145         /*
146          * remove a non-existent entry - oops
147          */
148         ASSERT (!"remove non-existent fmask");
149     } else {
150         hash_unset(bier_fmask_db.bfdb_hash, fmid);
151     }
152 }
153
154 void
155 bier_fmask_db_walk (bier_fmask_walk_fn_t fn, void *ctx)
156 {
157     CLIB_UNUSED (bier_fmask_id_t *fmid);
158     uword *bfmi;
159
160     hash_foreach(fmid, bfmi, bier_fmask_db.bfdb_hash,
161     ({
162         if (WALK_STOP == fn(*bfmi, ctx))
163             break;
164     }));
165 }
166
167 clib_error_t *
168 bier_fmask_db_module_init (vlib_main_t *vm)
169 {
170     bier_fmask_db.bfdb_hash = hash_create_mem(0,
171                                               sizeof(bier_fmask_id_t),
172                                               sizeof(index_t));
173
174     return (NULL);
175 }
176
177 VLIB_INIT_FUNCTION (bier_fmask_db_module_init);