35 #include <netlink-private/netlink.h> 36 #include <netlink-private/tc.h> 37 #include <netlink/netlink.h> 38 #include <netlink/utils.h> 39 #include <netlink/route/pktloc.h> 41 #include "pktloc_syntax.h" 42 #include "pktloc_grammar.h" 45 #define PKTLOC_NAME_HT_SIZ 256 47 static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ];
50 static unsigned int pktloc_hash(
const char *str)
52 unsigned long hash = 5381;
56 hash = ((hash << 5) + hash) + c;
58 return hash % PKTLOC_NAME_HT_SIZ;
61 static int __pktloc_lookup(
const char *name,
struct rtnl_pktloc **result)
66 hash = pktloc_hash(name);
67 nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) {
68 if (!strcasecmp(loc->name, name)) {
75 return -NLE_OBJ_NOTFOUND;
78 extern int pktloc_parse(
void *scanner);
80 static void rtnl_pktloc_free(
struct rtnl_pktloc *loc)
89 static int read_pktlocs(
void)
92 yyscan_t scanner = NULL;
93 static time_t last_read;
99 if (build_sysconf_path(&path,
"pktloc") < 0)
103 if (stat(path, &st) == 0) {
105 if (last_read == st.st_mtime) {
111 NL_DBG(2,
"Reading packet location file \"%s\"\n", path);
113 if (!(fd = fopen(path,
"re"))) {
114 err = -NLE_PKTLOC_FILE;
118 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) {
121 nl_list_for_each_entry_safe(loc, n, &pktloc_name_ht[i], list)
124 nl_init_list_head(&pktloc_name_ht[i]);
127 if ((err = pktloc_lex_init(&scanner)) < 0) {
132 buf = pktloc__create_buffer(fd, YY_BUF_SIZE, scanner);
133 pktloc__switch_to_buffer(buf, scanner);
135 if ((err = pktloc_parse(scanner)) != 0) {
136 pktloc__delete_buffer(buf, scanner);
137 err = -NLE_PARSE_ERR;
141 last_read = st.st_mtime;
144 pktloc_lex_destroy(scanner);
178 if ((err = read_pktlocs()) < 0)
181 return __pktloc_lookup(name, result);
191 if (!(loc = calloc(1,
sizeof(*loc))))
195 nl_init_list_head(&loc->list);
210 if (loc->refcnt <= 0)
211 rtnl_pktloc_free(loc);
224 if (__pktloc_lookup(loc->name, &l) == 0) {
229 NL_DBG(2,
"New packet location entry \"%s\" align=%u layer=%u " 230 "offset=%u mask=%#x shift=%u refnt=%u\n",
231 loc->name, loc->align, loc->layer, loc->offset,
232 loc->mask, loc->shift, loc->refcnt);
234 nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]);
239 void rtnl_pktloc_foreach(
void (*cb)(
struct rtnl_pktloc *,
void *),
void *arg)
247 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
248 nl_list_for_each_entry(loc, &pktloc_name_ht[i], list)
252 static int __init pktloc_init(
void)
256 for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
257 nl_init_list_head(&pktloc_name_ht[i]);
struct rtnl_pktloc * rtnl_pktloc_alloc(void)
Allocate packet location object.
void rtnl_pktloc_put(struct rtnl_pktloc *loc)
Return reference of a packet location.
int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **result)
Lookup packet location alias.
int rtnl_pktloc_add(struct rtnl_pktloc *loc)
Add a packet location to the hash table.