28#include <netlink-private/netlink.h>
29#include <netlink-private/tc.h>
30#include <netlink/netlink.h>
31#include <netlink/utils.h>
32#include <netlink/route/pktloc.h>
34#include "pktloc_syntax.h"
35#include "pktloc_grammar.h"
38#define PKTLOC_NAME_HT_SIZ 256
40static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ];
43static unsigned int pktloc_hash(
const char *str)
45 unsigned long hash = 5381;
49 hash = ((hash << 5) + hash) + c;
51 return hash % PKTLOC_NAME_HT_SIZ;
54static int __pktloc_lookup(
const char *name,
struct rtnl_pktloc **result)
59 hash = pktloc_hash(name);
60 nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) {
61 if (!strcasecmp(loc->name, name)) {
68 return -NLE_OBJ_NOTFOUND;
71extern int pktloc_parse(
void *scanner);
73static void rtnl_pktloc_free(
struct rtnl_pktloc *loc)
82static int read_pktlocs(
void)
84 YY_BUFFER_STATE buf = NULL;
85 yyscan_t scanner = NULL;
86 static time_t last_read;
92 if (build_sysconf_path(&path,
"pktloc") < 0)
96 if (stat(path, &st) == 0) {
98 if (last_read == st.st_mtime) {
104 NL_DBG(2,
"Reading packet location file \"%s\"\n", path);
106 if (!(fd = fopen(path,
"re"))) {
107 err = -NLE_PKTLOC_FILE;
111 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) {
114 nl_list_for_each_entry_safe(loc, n, &pktloc_name_ht[i], list)
117 nl_init_list_head(&pktloc_name_ht[i]);
120 if (pktloc_lex_init(&scanner) < 0) {
125 buf = pktloc__create_buffer(fd, YY_BUF_SIZE, scanner);
126 pktloc__switch_to_buffer(buf, scanner);
128 if ((err = pktloc_parse(scanner)) != 0) {
129 pktloc__delete_buffer(buf, scanner);
130 err = -NLE_PARSE_ERR;
134 last_read = st.st_mtime;
137 pktloc_lex_destroy(scanner);
171 if ((err = read_pktlocs()) < 0)
174 return __pktloc_lookup(name, result);
184 if (!(loc = calloc(1,
sizeof(*loc))))
188 nl_init_list_head(&loc->list);
203 if (loc->refcnt <= 0)
204 rtnl_pktloc_free(loc);
217 if (__pktloc_lookup(loc->name, &l) == 0) {
222 NL_DBG(2,
"New packet location entry \"%s\" align=%u layer=%u "
223 "offset=%u mask=%#x shift=%u refnt=%u\n",
224 loc->name, loc->align, loc->layer, loc->offset,
225 loc->mask, loc->shift, loc->refcnt);
227 nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]);
232void rtnl_pktloc_foreach(
void (*cb)(
struct rtnl_pktloc *,
void *),
void *arg)
240 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
241 nl_list_for_each_entry(loc, &pktloc_name_ht[i], list)
245static int __init pktloc_init(
void)
249 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
250 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.