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 * 98cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Graf * Copyright (c) 2003-2008 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> 26db5bd57899affbcaf42ac0b93c5c7be8f51ca390Thomas Graf#include <sys/stat.h> 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <sys/socket.h> 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <inttypes.h> 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <assert.h> 30d59883b117caecd19a9de58164defcc9a91a0caaThomas Graf#include <limits.h> 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <arpa/inet.h> 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netdb.h> 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifndef SOL_NETLINK 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define SOL_NETLINK 270 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf 391a125f88d8f46cad4ecbb9d19cfaddec63a26d0aPhilip Craig#include <linux/types.h> 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* local header copies */ 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if.h> 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if_arp.h> 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/if_ether.h> 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/pkt_sched.h> 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/pkt_cls.h> 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/gen_stats.h> 48865bbb464a08ef2c20238cb17337423763d6f0caThomas Graf#include <linux/ip_mp_alg.h> 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/handlers.h> 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/cache.h> 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/tc.h> 54508685c269275cb7ba3471c75abc689b4e3839b1Thomas Graf#include <netlink/object-api.h> 553040a1d6254465bed9e44e4d1bf279c2c50cd16aThomas Graf#include <netlink/cache-api.h> 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-types.h> 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf 5844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct trans_tbl { 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *a; 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __ADD(id, name) { .i = id, .a = #name }, 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf 6544d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct trans_list { 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf int i; 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf char *a; 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_list_head list; 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_DEBUG 1 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_DBG(LVL,FMT,ARG...) \ 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (LVL <= nl_debug) \ 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "DBG<" #LVL ">: " FMT, ##ARG); \ 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define BUG() \ 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf do { \ 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "BUG: %s:%d\n", \ 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf __FILE__, __LINE__); \ 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0); \ 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf } while (0) 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf 8644d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int __nl_read_num_str_file(const char *path, 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf int (*cb)(long, const char *)); 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf 898cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern int __trans_list_add(int, const char *, struct nl_list_head *); 908cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern void __trans_list_clear(struct nl_list_head *); 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf 928cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern char *__type2str(int, char *, size_t, struct trans_tbl *, size_t); 938cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern int __str2type(const char *, struct trans_tbl *, size_t); 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf 958cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern char *__list_type2str(int, char *, size_t, struct nl_list_head *); 968cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern int __list_str2type(const char *, struct nl_list_head *); 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf 988cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern char *__flags2str(int, char *, size_t, struct trans_tbl *, size_t); 998cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern int __str2flags(const char *, struct trans_tbl *, size_t); 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf 1018cd39c9f4ca8731279ea6467a9d489902fcae7f9Thomas Grafextern void dump_from_ops(struct nl_object *, struct nl_dump_params *); 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf 10344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline struct nl_cache *dp_cache(struct nl_object *obj) 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (obj->ce_cache == NULL) 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_cache_mngt_require(obj->ce_ops->oo_name); 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf return obj->ce_cache; 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf 11144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg) 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf return cb->cb_set[type](msg, cb->cb_args[type]); 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __init __attribute__ ((constructor)) 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define __exit __attribute__ ((destructor)) 120e38716b41e79b2d60ab9b7ada9678e1014a6898eHolger Schurig#undef __deprecated 121dbcdf91a99d0e12d012308328bc6e1894403a99bThomas Graf#define __deprecated __attribute__ ((deprecated)) 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define min(x,y) ({ \ 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(x) _x = (x); \ 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(y) _y = (y); \ 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf (void) (&_x == &_y); \ 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf _x < _y ? _x : _y; }) 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf 12944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define max(x,y) ({ \ 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(x) _x = (x); \ 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf typeof(y) _y = (y); \ 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf (void) (&_x == &_y); \ 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf _x > _y ? _x : _y; }) 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define min_t(type,x,y) \ 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define max_t(type,x,y) \ 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf 14044d362409d5469aed47d19e7908d19bd194493aThomas Grafextern int nl_cache_parse(struct nl_cache_ops *, struct sockaddr_nl *, 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nlmsghdr *, struct nl_parser_param *); 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf 14444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst, 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct tc_ratespec *src) 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_cell_log = src->cell_log; 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_feature = src->feature; 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_addend = src->addend; 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_mpu = src->mpu; 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rs_rate = src->rate; 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf 15444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst, 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_ratespec *src) 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->cell_log = src->rs_cell_log; 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->feature = src->rs_feature; 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->addend = src->rs_addend; 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->mpu = src->rs_mpu; 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->rate = src->rs_rate; 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf 16444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline char *nl_cache_name(struct nl_cache *cache) 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf return cache->c_ops ? cache->c_ops->co_name : "unknown"; 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define GENL_FAMILY(id, name) \ 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf { \ 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf { id, NL_ACT_UNSPEC, name }, \ 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, \ 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf 175cfcfca070355b246028df60da79813f09ed65755Thomas Grafstatic inline int wait_for_ack(struct nl_sock *sk) 176cfcfca070355b246028df60da79813f09ed65755Thomas Graf{ 177cfcfca070355b246028df60da79813f09ed65755Thomas Graf if (sk->s_flags & NL_NO_AUTO_ACK) 178cfcfca070355b246028df60da79813f09ed65755Thomas Graf return 0; 179cfcfca070355b246028df60da79813f09ed65755Thomas Graf else 180cfcfca070355b246028df60da79813f09ed65755Thomas Graf return nl_wait_for_ack(sk); 181cfcfca070355b246028df60da79813f09ed65755Thomas Graf} 182cfcfca070355b246028df60da79813f09ed65755Thomas Graf 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 184