34 #include <netlink-private/netlink.h>
35 #include <netlink-private/tc.h>
36 #include <netlink/netlink.h>
37 #include <netlink/utils.h>
38 #include <netlink/route/pktloc.h>
40 #include "pktloc_syntax.h"
41 #include "pktloc_grammar.h"
44 #define PKTLOC_NAME_HT_SIZ 256
46 static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ];
49 static unsigned int pktloc_hash(
const char *str)
51 unsigned long hash = 5381;
55 hash = ((hash << 5) + hash) + c;
57 return hash % PKTLOC_NAME_HT_SIZ;
60 static int __pktloc_lookup(
const char *name,
struct rtnl_pktloc **result)
65 hash = pktloc_hash(name);
66 nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) {
67 if (!strcasecmp(loc->name, name)) {
74 return -NLE_OBJ_NOTFOUND;
77 extern int pktloc_parse(
void *scanner);
79 static void rtnl_pktloc_free(
struct rtnl_pktloc *loc)
88 static int read_pktlocs(
void)
91 yyscan_t scanner = NULL;
92 static time_t last_read;
98 if (build_sysconf_path(&path,
"pktloc") < 0)
102 if (stat(path, &st) == 0) {
104 if (last_read == st.st_mtime)
108 NL_DBG(2,
"Reading packet location file \"%s\"\n", path);
110 if (!(fd = fopen(path,
"r"))) {
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 ((err = 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;
142 pktloc_lex_destroy(scanner);
176 if ((err = read_pktlocs()) < 0)
179 return __pktloc_lookup(name, result);
189 if (!(loc = calloc(1,
sizeof(*loc))))
193 nl_init_list_head(&loc->list);
208 if (loc->refcnt <= 0)
209 rtnl_pktloc_free(loc);
222 if (__pktloc_lookup(loc->name, &l) == 0) {
227 NL_DBG(2,
"New packet location entry \"%s\" align=%u layer=%u "
228 "offset=%u mask=%#x shift=%u refnt=%u\n",
229 loc->name, loc->align, loc->layer, loc->offset,
230 loc->mask, loc->shift, loc->refcnt);
232 nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]);
237 void rtnl_pktloc_foreach(
void (*cb)(
struct rtnl_pktloc *,
void *),
void *arg)
245 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
246 nl_list_for_each_entry(loc, &pktloc_name_ht[i], list)
250 static int __init pktloc_init(
void)
254 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
255 nl_init_list_head(&pktloc_name_ht[i]);