28#include "nl-default.h"
32#include <netlink/netlink.h>
33#include <netlink/utils.h>
34#include <netlink/route/pktloc.h>
38#include "pktloc_syntax.h"
39#include "pktloc_grammar.h"
42#define PKTLOC_NAME_HT_SIZ 256
44static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ];
47static unsigned int pktloc_hash(
const char *str)
49 unsigned long hash = 5381;
53 hash = ((hash << 5) + hash) + c;
55 return hash % PKTLOC_NAME_HT_SIZ;
58static int __pktloc_lookup(
const char *name,
struct rtnl_pktloc **result)
63 hash = pktloc_hash(name);
64 nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) {
65 if (!strcasecmp(loc->name, name)) {
72 return -NLE_OBJ_NOTFOUND;
75extern int pktloc_parse(
void *scanner);
77static void rtnl_pktloc_free(
struct rtnl_pktloc *loc)
86static int read_pktlocs(
void)
89 yyscan_t scanner = NULL;
90 static time_t last_read;
96 if (build_sysconf_path(&path,
"pktloc") < 0)
100 if (stat(path, &st) == 0) {
102 if (last_read == st.st_mtime) {
108 NL_DBG(2,
"Reading packet location file \"%s\"\n", path);
110 if (!(fd = fopen(path,
"re"))) {
111 err = -NLE_PKTLOC_FILE;
115 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) {
118 nl_list_for_each_entry_safe(loc, n, &pktloc_name_ht[i], list)
121 nl_init_list_head(&pktloc_name_ht[i]);
124 if (pktloc_lex_init(&scanner) < 0) {
129 buf = pktloc__create_buffer(fd, YY_BUF_SIZE, scanner);
130 pktloc__switch_to_buffer(buf, scanner);
132 if ((err = pktloc_parse(scanner)) != 0) {
133 pktloc__delete_buffer(buf, scanner);
134 err = -NLE_PARSE_ERR;
138 last_read = st.st_mtime;
141 pktloc_lex_destroy(scanner);
175 if ((err = read_pktlocs()) < 0)
178 return __pktloc_lookup(name, result);
188 if (!(loc = calloc(1,
sizeof(*loc))))
192 nl_init_list_head(&loc->list);
207 if (loc->refcnt <= 0)
208 rtnl_pktloc_free(loc);
221 if (__pktloc_lookup(loc->name, &l) == 0) {
226 NL_DBG(2,
"New packet location entry \"%s\" align=%u layer=%u "
227 "offset=%u mask=%#x shift=%u refnt=%u\n",
228 loc->name, loc->align, loc->layer, loc->offset,
229 loc->mask, loc->shift, loc->refcnt);
231 nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]);
236void rtnl_pktloc_foreach(
void (*cb)(
struct rtnl_pktloc *,
void *),
void *arg)
244 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
245 nl_list_for_each_entry(loc, &pktloc_name_ht[i], list)
249static int _nl_init pktloc_init(
void)
253 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
254 nl_init_list_head(&pktloc_name_ht[i]);
int rtnl_pktloc_add(struct rtnl_pktloc *loc)
Add a packet location to the hash table.
int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **result)
Lookup packet location alias.
void rtnl_pktloc_put(struct rtnl_pktloc *loc)
Return reference of a packet location.
struct rtnl_pktloc * rtnl_pktloc_alloc(void)
Allocate packet location object.