00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <netlink-local.h>
00019 #include <netlink/netlink.h>
00020 #include <netlink/cache.h>
00021 #include <netlink/utils.h>
00022
00023 static struct nl_cache_ops *cache_ops;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 struct nl_cache_ops *nl_cache_ops_lookup(const char *name)
00038 {
00039 struct nl_cache_ops *ops;
00040
00041 for (ops = cache_ops; ops; ops = ops->co_next)
00042 if (!strcmp(ops->co_name, name))
00043 return ops;
00044
00045 return NULL;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 struct nl_cache_ops *nl_cache_ops_associate(int protocol, int msgtype)
00060 {
00061 int i;
00062 struct nl_cache_ops *ops;
00063
00064 for (ops = cache_ops; ops; ops = ops->co_next) {
00065 if (ops->co_protocol != protocol)
00066 continue;
00067
00068 for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
00069 if (ops->co_msgtypes[i].mt_id == msgtype)
00070 return ops;
00071 }
00072
00073 return NULL;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 struct nl_msgtype *nl_msgtype_lookup(struct nl_cache_ops *ops, int msgtype)
00087 {
00088 int i;
00089
00090 for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
00091 if (ops->co_msgtypes[i].mt_id == msgtype)
00092 return &ops->co_msgtypes[i];
00093
00094 return NULL;
00095 }
00096
00097 static struct nl_cache_ops *cache_ops_lookup_for_obj(struct nl_object_ops *obj_ops)
00098 {
00099 struct nl_cache_ops *ops;
00100
00101 for (ops = cache_ops; ops; ops = ops->co_next)
00102 if (ops->co_obj_ops == obj_ops)
00103 return ops;
00104
00105 return NULL;
00106
00107 }
00108
00109
00110
00111
00112
00113
00114 void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *arg)
00115 {
00116 struct nl_cache_ops *ops;
00117
00118 for (ops = cache_ops; ops; ops = ops->co_next)
00119 cb(ops, arg);
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 int nl_cache_mngt_register(struct nl_cache_ops *ops)
00132 {
00133 if (!ops->co_name || !ops->co_obj_ops)
00134 return -NLE_INVAL;
00135
00136 if (nl_cache_ops_lookup(ops->co_name))
00137 return -NLE_EXIST;
00138
00139 ops->co_next = cache_ops;
00140 cache_ops = ops;
00141
00142 NL_DBG(1, "Registered cache operations %s\n", ops->co_name);
00143
00144 return 0;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
00159 {
00160 struct nl_cache_ops *t, **tp;
00161
00162 for (tp = &cache_ops; (t=*tp) != NULL; tp = &t->co_next)
00163 if (t == ops)
00164 break;
00165
00166 if (!t)
00167 return -NLE_NOCACHE;
00168
00169 NL_DBG(1, "Unregistered cache operations %s\n", ops->co_name);
00170
00171 *tp = t->co_next;
00172 return 0;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void nl_cache_mngt_provide(struct nl_cache *cache)
00191 {
00192 struct nl_cache_ops *ops;
00193
00194 ops = cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops);
00195 if (!ops)
00196 BUG();
00197 else
00198 ops->co_major_cache = cache;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 void nl_cache_mngt_unprovide(struct nl_cache *cache)
00210 {
00211 struct nl_cache_ops *ops;
00212
00213 ops = cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops);
00214 if (!ops)
00215 BUG();
00216 else if (ops->co_major_cache == cache)
00217 ops->co_major_cache = NULL;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 struct nl_cache *nl_cache_mngt_require(const char *name)
00231 {
00232 struct nl_cache_ops *ops;
00233
00234 ops = nl_cache_ops_lookup(name);
00235 if (!ops || !ops->co_major_cache) {
00236 fprintf(stderr, "Application BUG: Your application must "
00237 "call nl_cache_mngt_provide() and\nprovide a valid "
00238 "%s cache to be used for internal lookups.\nSee the "
00239 " API documentation for more details.\n", name);
00240
00241 return NULL;
00242 }
00243
00244 return ops->co_major_cache;
00245 }
00246
00247
00248
00249