netlink-local.h revision dbcdf91a99d0e12d012308328bc6e1894403a99b
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 371a125f88d8f46cad4ecbb9d19cfaddec63a26d0aPhilip Craig#include <linux/types.h> 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf/* local header copies */ 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if.h> 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if_arp.h> 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if_ether.h> 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/pkt_sched.h> 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/pkt_cls.h> 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/gen_stats.h> 46865bbb464a08ef2c20238cb17337423763d6f0caThomas Graf#include <linux/ip_mp_alg.h> 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/handlers.h> 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/cache.h> 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/tc.h> 52508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#include <netlink/object-api.h> 533040a1d6254465bed9e44e4d1bf279c2c50cd16aThomas Graf#include <netlink/cache-api.h> 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-types.h> 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf 5644d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct trans_tbl { 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *a; 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __ADD(id, name) { .i = id, .a = #name }, 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf 6344d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct trans_list { 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf char *a; 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head list; 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_DEBUG 1 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_DBG(LVL,FMT,ARG...) \ 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (LVL <= nl_debug) \ 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "DBG<" #LVL ">: " FMT, ##ARG); \ 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define BUG() \ 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "BUG: %s:%d\n", \ 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf __FILE__, __LINE__); \ 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0); \ 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define RET_ERR(R, E) \ 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf errno = E; \ 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf return -R; \ 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf 9044d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int __nl_error(int, const char *, unsigned int, 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *, const char *, ...); 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf 9344d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int __nl_read_num_str_file(const char *path, 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf int (*cb)(long, const char *)); 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifdef NL_ERROR_ASSERT 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <assert.h> 9844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __assert_error(const char *file, int line, char *func, 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *fmt, ...) 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf va_list args; 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "%s:%d:%s: ", file, line, func); 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf va_start(args, fmt); 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf vfprintf(stderr, fmt, args); 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf va_end(args); 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "\n"); 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0); 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_error(E, FMT,ARG...) \ 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf __assert_error(__FILE__, __LINE__, __FUNCTION__, FMT, ##ARG) 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf#else 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_error(E, FMT,ARG...) \ 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf __nl_error(E, __FILE__, __LINE__, __FUNCTION__, FMT, ##ARG) 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_errno(E) nl_error(E, NULL) 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf 121508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf/* backwards compat */ 122508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#define dp_new_line(params, line) nl_new_line(params, line) 123508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#define dp_dump(params, fmt, arg...) nl_dump(params, fmt, ##arg) 124508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf 12544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __trans_list_add(int i, const char *a, 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head *head) 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl; 12944d362409d5469aed47d19e7908d19bd194493aThomas Graf 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf tl = calloc(1, sizeof(*tl)); 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!tl) 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_errno(ENOMEM); 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf tl->i = i; 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf tl->a = strdup(a); 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_add_tail(&tl->list, head); 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf 14244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __trans_list_clear(struct nl_list_head *head) 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl, *next; 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry_safe(tl, next, head, list) { 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf free(tl->a); 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf free(tl); 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf 15244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *__type2str(int type, char *buf, size_t len, 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_tbl *tbl, size_t tbl_len) 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) { 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tbl[i].i == type) { 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "%s", tbl[i].a); 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "0x%x", type); 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf 16744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *__list_type2str(int type, char *buf, size_t len, 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head *head) 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl; 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(tl, head, list) { 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tl->i == type) { 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "%s", tl->a); 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf snprintf(buf, len, "0x%x", type); 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf 18344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *__flags2str(int flags, char *buf, size_t len, 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_tbl *tbl, size_t tbl_len) 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf int tmp = flags; 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf memset(buf, 0, len); 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) { 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tbl[i].i & tmp) { 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf tmp &= ~tbl[i].i; 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(buf, tbl[i].a, len - strlen(buf) - 1); 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf if ((tmp & flags)) 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(buf, ",", len - strlen(buf) - 1); 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf return buf; 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf 20344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __str2type(const char *buf, struct trans_tbl *tbl, 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t tbl_len) 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned long l; 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf char *end; 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*buf == '\0') 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcasecmp(tbl[i].a, buf)) 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf return tbl[i].i; 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf l = strtoul(buf, &end, 0); 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l == ULONG_MAX || *end != '\0') 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf return (int) l; 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf 22444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __list_str2type(const char *buf, struct nl_list_head *head) 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct trans_list *tl; 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned long l; 22844d362409d5469aed47d19e7908d19bd194493aThomas Graf char *end; 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*buf == '\0') 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(tl, head, list) { 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcasecmp(tl->a, buf)) 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf return tl->i; 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf l = strtoul(buf, &end, 0); 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l == ULONG_MAX || *end != '\0') 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf return -1; 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf return (int) l; 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf 24544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int __str2flags(const char *buf, struct trans_tbl *tbl, 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t tbl_len) 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, flags = 0, len; 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf char *p = (char *) buf, *t; 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf for (;;) { 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*p == ' ') 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf p++; 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf t = strchr(p, ','); 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf len = t ? t - p : strlen(p); 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < tbl_len; i++) 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strncasecmp(tbl[i].a, p, len)) 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf flags |= tbl[i].i; 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!t) 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf return flags; 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf p = ++t; 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf 27044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __dp_dump(struct nl_dump_params *parms, const char *fmt, 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf va_list args) 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (parms->dp_fd) 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf vfprintf(parms->dp_fd, fmt, args); 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (parms->dp_buf || parms->dp_cb) { 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf char *buf = NULL; 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf vasprintf(&buf, fmt, args); 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (parms->dp_cb) 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf parms->dp_cb(parms, buf); 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf strncat(parms->dp_buf, buf, 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf parms->dp_buflen - strlen(parms->dp_buf) - 1); 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf free(buf); 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf 28744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void dp_dump_line(struct nl_dump_params *parms, int line, 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *fmt, ...) 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf va_list args; 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf 292508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf nl_new_line(parms, line); 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf va_start(args, fmt); 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf __dp_dump(parms, fmt, args); 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf va_end(args); 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf 29944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void dump_from_ops(struct nl_object *obj, 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_dump_params *params) 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf int type = params->dp_type; 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (type < 0 || type > NL_DUMP_MAX) 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf BUG(); 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (params->dp_dump_msgtype) { 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf /* XXX */ 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(params, 0, "%s ", 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_type2name(obj->ce_ops, 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf obj->ce_ops->co_protocol, 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf obj->ce_msgtype, 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf params->dp_pre_dump = 1; 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(params, 0); 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (obj->ce_ops->oo_dump[type]) 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf obj->ce_ops->oo_dump[type](obj, params); 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf 32644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline struct nl_cache *dp_cache(struct nl_object *obj) 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (obj->ce_cache == NULL) 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_cache_mngt_require(obj->ce_ops->oo_name); 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf return obj->ce_cache; 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf 33444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg) 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf return cb->cb_set[type](msg, cb->cb_args[type]); 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __init __attribute__ ((constructor)) 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __exit __attribute__ ((destructor)) 344dbcdf91a99d0e12d012308328bc6e1894403a99bThomas Graf#define __deprecated __attribute__ ((deprecated)) 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define P_ACCEPT 0 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define P_IGNORE 0 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define min(x,y) ({ \ 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(x) _x = (x); \ 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(y) _y = (y); \ 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf (void) (&_x == &_y); \ 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf _x < _y ? _x : _y; }) 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define max(x,y) ({ \ 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(x) _x = (x); \ 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(y) _y = (y); \ 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf (void) (&_x == &_y); \ 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf _x > _y ? _x : _y; }) 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define min_t(type,x,y) \ 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define max_t(type,x,y) \ 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf 36644d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int nl_cache_parse(struct nl_cache_ops *, struct sockaddr_nl *, 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nlmsghdr *, struct nl_parser_param *); 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf 37044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst, 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct tc_ratespec *src) 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_cell_log = src->cell_log; 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_feature = src->feature; 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_addend = src->addend; 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_mpu = src->mpu; 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_rate = src->rate; 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37944d362409d5469aed47d19e7908d19bd194493aThomas Graf 38044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst, 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_ratespec *src) 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->cell_log = src->rs_cell_log; 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->feature = src->rs_feature; 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->addend = src->rs_addend; 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->mpu = src->rs_mpu; 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rate = src->rs_rate; 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf 39044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *nl_cache_name(struct nl_cache *cache) 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf return cache->c_ops ? cache->c_ops->co_name : "unknown"; 39344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define GENL_FAMILY(id, name) \ 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf { \ 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf { id, NL_ACT_UNSPEC, name }, \ 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, \ 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 402