netlink-local.h revision 3040a1d6254465bed9e44e4d1bf279c2c50cd16a
144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * netlink-local.h Local Netlink Interface 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifndef NETLINK_LOCAL_H_ 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NETLINK_LOCAL_H_ 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <stdio.h> 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <errno.h> 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <stdlib.h> 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <string.h> 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <unistd.h> 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <fcntl.h> 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <math.h> 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <time.h> 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <stdarg.h> 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <ctype.h> 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <sys/types.h> 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <sys/socket.h> 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <inttypes.h> 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <assert.h> 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <arpa/inet.h> 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netdb.h> 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifndef SOL_NETLINK 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define SOL_NETLINK 270 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf 3744d362409d5469aed47d19e7908d19bd194493aThomas Graftypedef uint8_t __u8; 3844d362409d5469aed47d19e7908d19bd194493aThomas Graftypedef uint16_t __u16; 3944d362409d5469aed47d19e7908d19bd194493aThomas Graftypedef int16_t __s16; 4044d362409d5469aed47d19e7908d19bd194493aThomas Graftypedef uint32_t __u32; 4144d362409d5469aed47d19e7908d19bd194493aThomas Graftypedef int32_t __s32; 4244d362409d5469aed47d19e7908d19bd194493aThomas Graftypedef uint64_t __u64; 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf/* local header copies */ 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if.h> 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if_arp.h> 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if_ether.h> 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/pkt_sched.h> 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/pkt_cls.h> 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/gen_stats.h> 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/handlers.h> 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/cache.h> 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/tc.h> 56508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#include <netlink/object-api.h> 573040a1d6254465bed9e44e4d1bf279c2c50cd16aThomas Graf#include <netlink/cache-api.h> 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-types.h> 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf 6044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct trans_tbl { 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *a; 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __ADD(id, name) { .i = id, .a = #name }, 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf 6744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct trans_list { 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf char *a; 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head list; 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_DEBUG 1 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_DBG(LVL,FMT,ARG...) \ 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (LVL <= nl_debug) \ 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "DBG<" #LVL ">: " FMT, ##ARG); \ 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define BUG() \ 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "BUG: %s:%d\n", \ 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf __FILE__, __LINE__); \ 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0); \ 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define RET_ERR(R, E) \ 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf errno = E; \ 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf return -R; \ 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf 9444d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int __nl_error(int, const char *, unsigned int, 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *, const char *, ...); 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf 9744d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int __nl_read_num_str_file(const char *path, 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf int (*cb)(long, const char *)); 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef NL_ERROR_ASSERT 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <assert.h> 10244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __assert_error(const char *file, int line, char *func, 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *fmt, ...) 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf va_list args; 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "%s:%d:%s: ", file, line, func); 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf va_start(args, fmt); 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf vfprintf(stderr, fmt, args); 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf va_end(args); 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "\n"); 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0); 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_error(E, FMT,ARG...) \ 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf __assert_error(__FILE__, __LINE__, __FUNCTION__, FMT, ##ARG) 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf#else 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_error(E, FMT,ARG...) \ 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf __nl_error(E, __FILE__, __LINE__, __FUNCTION__, FMT, ##ARG) 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_errno(E) nl_error(E, NULL) 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf 125508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf/* backwards compat */ 126508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#define dp_new_line(params, line) nl_new_line(params, line) 127508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#define dp_dump(params, fmt, arg...) nl_dump(params, fmt, ##arg) 128508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 12944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __trans_list_add(int i, const char *a, 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head *head) 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl; 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf tl = calloc(1, sizeof(*tl)); 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!tl) 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_errno(ENOMEM); 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf tl->i = i; 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf tl->a = strdup(a); 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_add_tail(&tl->list, head); 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf 14644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __trans_list_clear(struct nl_list_head *head) 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl, *next; 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry_safe(tl, next, head, list) { 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf free(tl->a); 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf free(tl); 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf 15644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *__type2str(int type, char *buf, size_t len, 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_tbl *tbl, size_t tbl_len) 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) { 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tbl[i].i == type) { 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "%s", tbl[i].a); 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "0x%x", type); 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf 17144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *__list_type2str(int type, char *buf, size_t len, 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head *head) 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl; 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(tl, head, list) { 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tl->i == type) { 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "%s", tl->a); 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "0x%x", type); 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf 18744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *__flags2str(int flags, char *buf, size_t len, 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_tbl *tbl, size_t tbl_len) 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf int tmp = flags; 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf memset(buf, 0, len); 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) { 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tbl[i].i & tmp) { 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf tmp &= ~tbl[i].i; 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(buf, tbl[i].a, len - strlen(buf) - 1); 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf if ((tmp & flags)) 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(buf, ",", len - strlen(buf) - 1); 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 20344d362409d5469aed47d19e7908d19bd194493aThomas Graf 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf 20744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __str2type(const char *buf, struct trans_tbl *tbl, 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t tbl_len) 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned long l; 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf char *end; 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*buf == '\0') 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcasecmp(tbl[i].a, buf)) 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf return tbl[i].i; 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf l = strtoul(buf, &end, 0); 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l == ULONG_MAX || *end != '\0') 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf return (int) l; 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf 22844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __list_str2type(const char *buf, struct nl_list_head *head) 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl; 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned long l; 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf char *end; 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*buf == '\0') 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(tl, head, list) { 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcasecmp(tl->a, buf)) 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf return tl->i; 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf l = strtoul(buf, &end, 0); 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l == ULONG_MAX || *end != '\0') 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf return (int) l; 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf 24944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __str2flags(const char *buf, struct trans_tbl *tbl, 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t tbl_len) 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, flags = 0, len; 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf char *p = (char *) buf, *t; 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf for (;;) { 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*p == ' ') 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf p++; 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf t = strchr(p, ','); 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf len = t ? t - p : strlen(p); 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strncasecmp(tbl[i].a, p, len)) 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf flags |= tbl[i].i; 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!t) 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf return flags; 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf p = ++t; 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf 27444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __dp_dump(struct nl_dump_params *parms, const char *fmt, 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf va_list args) 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (parms->dp_fd) 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf vfprintf(parms->dp_fd, fmt, args); 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (parms->dp_buf || parms->dp_cb) { 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf char *buf = NULL; 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf vasprintf(&buf, fmt, args); 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (parms->dp_cb) 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf parms->dp_cb(parms, buf); 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf else 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(parms->dp_buf, buf, 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf parms->dp_buflen - strlen(parms->dp_buf) - 1); 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf free(buf); 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf 29144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void dp_dump_line(struct nl_dump_params *parms, int line, 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *fmt, ...) 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf va_list args; 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf 296508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf nl_new_line(parms, line); 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf va_start(args, fmt); 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf __dp_dump(parms, fmt, args); 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf va_end(args); 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf 30344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void dump_from_ops(struct nl_object *obj, 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_dump_params *params) 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf int type = params->dp_type; 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (type < 0 || type > NL_DUMP_MAX) 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf BUG(); 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (params->dp_dump_msgtype) { 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf /* XXX */ 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(params, 0, "%s ", 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_type2name(obj->ce_ops, 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf obj->ce_ops->co_protocol, 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf obj->ce_msgtype, 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf params->dp_pre_dump = 1; 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(params, 0); 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (obj->ce_ops->oo_dump[type]) 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf obj->ce_ops->oo_dump[type](obj, params); 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf 33044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline struct nl_cache *dp_cache(struct nl_object *obj) 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (obj->ce_cache == NULL) 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_cache_mngt_require(obj->ce_ops->oo_name); 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf return obj->ce_cache; 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf 33844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg) 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf return cb->cb_set[type](msg, cb->cb_args[type]); 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __init __attribute__ ((constructor)) 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __exit __attribute__ ((destructor)) 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define P_ACCEPT 0 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define P_IGNORE 0 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define min(x,y) ({ \ 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(x) _x = (x); \ 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(y) _y = (y); \ 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf (void) (&_x == &_y); \ 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf _x < _y ? _x : _y; }) 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define max(x,y) ({ \ 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(x) _x = (x); \ 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(y) _y = (y); \ 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf (void) (&_x == &_y); \ 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf _x > _y ? _x : _y; }) 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define min_t(type,x,y) \ 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define max_t(type,x,y) \ 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf 36944d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int nl_cache_parse(struct nl_cache_ops *, struct sockaddr_nl *, 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nlmsghdr *, struct nl_parser_param *); 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf 37344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst, 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct tc_ratespec *src) 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_cell_log = src->cell_log; 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_feature = src->feature; 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_addend = src->addend; 37944d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_mpu = src->mpu; 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_rate = src->rate; 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf 38344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst, 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_ratespec *src) 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->cell_log = src->rs_cell_log; 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->feature = src->rs_feature; 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->addend = src->rs_addend; 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->mpu = src->rs_mpu; 39044d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rate = src->rs_rate; 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf 39344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *nl_cache_name(struct nl_cache *cache) 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf return cache->c_ops ? cache->c_ops->co_name : "unknown"; 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define GENL_FAMILY(id, name) \ 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf { \ 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf { id, NL_ACT_UNSPEC, name }, \ 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, \ 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 405