wiki.slank.dev Logo
latest

netlink book

  • Structure Types and Enums Cheatsheet
  • Netlink Configuration Examples
  • Netlink Helper inline functions
  • Hexdump util c-func
  • FRR/ZEBRA Internals
  • FRR/BGPd Internals
  • Netlink Book :: はじめに
  • Netlink Book :: Netlinkとはなにか

system software

  • Linux
  • KVM
  • QEMU
  • BPF (eBPF / bpftools / BCC)
  • DPDK
  • OpenStack
  • Vagrant
  • ipftrace

misc

  • Prometheus
  • Consul
  • Ansible
  • jq
  • etcd
  • python
  • Xmonadの環境構築
  • sshでの作業
  • 実機での作業
  • トラブルシューティング
  • MBP用の設定
  • VPP
  • Tshark / tshark
  • Trex: Software Traffic Generator by cisco
  • Docker
  • LXD/LXC
  • Kubernetes
  • Arch Linux インストールバトル 2015/09/08
  • Linuxカーネル構築の伝統的方法
  • performance tools
  • TestPMD
  • ISC-DHCP server
  • Open vSwitch
  • OVS-dpdk
  • Pktgen-DPDK
  • Spirent
  • OpenVPN
  • すべてのパケットをキャプチャする
  • GoBGP
  • nginx / NGINX
  • gRPC c++ usage
  • Sphinx ドキュメント
  • CPUクロック速度の設定
  • Graphviz
  • Systemtap導入方法
  • valgring つかってみた
  • Wordpressの環境構築
  • WordPressのバックアップの手順
  • WordPressのコンテンツ復元の手順
  • DC作業KIT
  • life-tips

Linux Distribution

  • Debian Package

NOS / Network OS

  • VyOS Setup
  • Cisco 1812J
  • JUNOS
  • Cisco IOS / IOS-XR / IOS-XE
  • Cumulus Linux
  • FRR / Quagga

Sehll

  • Zshチートシート
  • Bash Cheatsheet

Unix tools

  • Mutt
  • OpenSSL
  • Gnuplot
  • Xclip
  • Travis-CI使い方
  • SSH Cheatsheet
  • GCCチートシート
  • GDB
  • Git Command チートシート
  • GNU Global Cheatsheet
  • Make チートシート
  • objdumpチートシート
  • Options
  • Xコマンドチートシート
  • Tmux
  • Vim
  • Regex Cheatsheet
  • cpupower 使い方
  • 研究室サーバ SSH ユーザ追加手順
  • Asmメモ
  • Mount Command Cheatsheet
  • RCS (Revision Control System)
  • Docker Command

Markup Language

  • Markdown 記法チートシート
  • ReST形式チートシート
  • Pandoc
  • Doxygen 使い方
  • TeX環境構築

Programming Language

  • matplotlib
  • Go lang
  • Coq
wiki.slank.dev
  • Docs »
  • Netlink Helper inline functions
  • Edit on GitHub

Netlink Helper inline functions¶

#ifndef _NETLINK_H_
#define _NETLINK_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/genetlink.h>

#define GENL_REQUEST(_req, _bufsiz, _family, _hdrsiz, _ver, _cmd, _flags) \
struct {                                                \
  struct nlmsghdr    n;                                 \
  struct genlmsghdr  g;                                 \
  char buf[NLMSG_ALIGN(_hdrsiz) + (_bufsiz)];           \
} _req = {                                              \
  .n = {                                                \
    .nlmsg_type = (_family),                            \
    .nlmsg_flags = (_flags),                            \
    .nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN + (_hdrsiz)), \
  },                                                    \
  .g = {                                                \
    .cmd = (_cmd),                                      \
    .version = (_ver),                                  \
  },                                                    \
}

#define NLMSG_TAIL(nmsg) \
  ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))

#define RTA_TAIL(rta) \
	((struct rtattr *) (((void *) (rta)) + \
					RTA_ALIGN((rta)->rta_len)))

static inline __u8 rta_getattr_u8(const struct rtattr *rta) { return *(__u8 *)RTA_DATA(rta); }
static inline __u16 rta_getattr_u16(const struct rtattr *rta) { return *(__u16 *)RTA_DATA(rta); }
static inline __u32 rta_getattr_u32(const struct rtattr *rta) { return *(__u32 *)RTA_DATA(rta); }
static inline __u64 rta_getattr_u64(const struct rtattr *rta) { return *(__u64 *)RTA_DATA(rta); }
static inline __s8 rta_getattr_s8(const struct rtattr *rta) { return *(__s8 *)RTA_DATA(rta); }
static inline __u16 rta_getattr_s16(const struct rtattr *rta) { return *(__s16 *)RTA_DATA(rta); }
static inline __s32 rta_getattr_s32(const struct rtattr *rta) { return *(__s32 *)RTA_DATA(rta); }
static inline __s64 rta_getattr_s64(const struct rtattr *rta) { return *(__s64 *)RTA_DATA(rta); }
static inline const char *rta_getattr_str(const struct rtattr *rta) { return (const char *)RTA_DATA(rta); }

static inline int
parse_rtattr_flags(struct rtattr *tb[],
    int max, struct rtattr *rta,
    int len, unsigned short flags)
{
  unsigned short type;
  memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
  while (RTA_OK(rta, len)) {
    type = rta->rta_type & ~flags;
    if ((type <= max) && (!tb[type]))
      tb[type] = rta;
    rta = RTA_NEXT(rta, len);
  }
  if (len)
    fprintf(stderr, "!!!Deficit %d, rta_len=%d\n",
      len, rta->rta_len);
  return 0;
}

static inline int
parse_rtattr(struct rtattr *tb[],
    int max, struct rtattr *rta, int len)
{ return parse_rtattr_flags(tb, max, rta, len, 0); }

static inline int
addattr_l(struct nlmsghdr *n, int maxlen,
    int type, const void *data, int alen)
{
  int len = RTA_LENGTH(alen);
  struct rtattr *rta;

  if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
    fprintf(stderr,
      "addattr_l ERROR: message exceeded bound of %d\n",
      maxlen);
    return -1;
  }
  rta = NLMSG_TAIL(n);
  rta->rta_type = type;
  rta->rta_len = len;
  if (alen)
    memcpy(RTA_DATA(rta), data, alen);
  n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
  return 0;
}

static inline int
addattr(struct nlmsghdr *n, int maxlen, int type)
{ return addattr_l(n, maxlen, type, NULL, 0); }
static inline int
addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data)
{ return addattr_l(n, maxlen, type, &data, sizeof(__u8)); }
static inline int
addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data)
{ return addattr_l(n, maxlen, type, &data, sizeof(__u16)); }
static inline int
addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
{ return addattr_l(n, maxlen, type, &data, sizeof(__u32)); }
static inline int
addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data)
{ return addattr_l(n, maxlen, type, &data, sizeof(__u64)); }
static inline int
addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *str)
{ return addattr_l(n, maxlen, type, str, strlen(str)+1); }

static inline int
nl_talk(int fd, struct nlmsghdr *n,
                struct nlmsghdr *answer, size_t answer_buf_siz)
{
  static char buf[10000];
  if (answer == NULL) {
    n->nlmsg_flags |= NLM_F_ACK;
    answer = (struct nlmsghdr*)buf;
    answer_buf_siz = sizeof(buf);
  }
  int ret = send(fd, n, n->nlmsg_len, 0);
  if (ret < 0) {
    perror("send");
    exit(1);
  }
  ret = recv(fd, answer, answer_buf_siz, 0);
  if (ret < 0) {
    perror("recv");
    exit(1);
  }
  return 0;
}

static inline int
rta_addattr_l(struct rtattr *rta, int maxlen, int type,
      const void *data, int alen)
{
  struct rtattr *subrta;
  int len = RTA_LENGTH(alen);

  if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) {
    fprintf(stderr,
      "rta_addattr_l: Error! max allowed bound %d exceeded\n",
      maxlen);
    return -1;
  }
  subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len));
  subrta->rta_type = type;
  subrta->rta_len = len;
  if (alen)
    memcpy(RTA_DATA(subrta), data, alen);
  rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len);
  return 0;
}

static inline int
rta_addattr8(struct rtattr *rta, int maxlen, int type, __u8 data)
{ return rta_addattr_l(rta, maxlen, type, &data, sizeof(__u8)); }

static inline int
rta_addattr16(struct rtattr *rta, int maxlen, int type, __u16 data)
{ return rta_addattr_l(rta, maxlen, type, &data, sizeof(__u16)); }

static inline int
rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
{ return rta_addattr_l(rta, maxlen, type, &data, sizeof(__u32)); }

static inline int
rta_addattr64(struct rtattr *rta, int maxlen, int type, __u64 data)
{ return rta_addattr_l(rta, maxlen, type, &data, sizeof(__u64)); }

static inline struct rtattr *
rta_nest(struct rtattr *rta, int maxlen, int type)
{
  struct rtattr *nest = RTA_TAIL(rta);
  rta_addattr_l(rta, maxlen, type, NULL, 0);
  nest->rta_type |= NLA_F_NESTED;
  return nest;
}

static inline int
rta_nest_end(struct rtattr *rta, struct rtattr *nest)
{
  nest->rta_len = (void *)RTA_TAIL(rta) - (void *)nest;
  return rta->rta_len;
}

static inline int
addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len)
{
  if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) {
    fprintf(stderr,
      "addraw_l ERROR: message exceeded bound of %d\n",
      maxlen);
    return -1;
  }

  memcpy(NLMSG_TAIL(n), data, len);
  memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len);
  n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len);
  return 0;
}

#endif /* _NETLINK_H_ */
Next Previous

© Copyright 2019, slankdev Revision a388a159.

Built with Sphinx using a theme provided by Read the Docs.