link: API for address family specific link data
Introduces a new API to handle address familiy specific link data such as IFLA_PROTINFO. It provides entry hooks for parsing IFLA_PROTINFO attributes and allows to include the parsed data when a link object is dumped.
This commit is contained in:
parent
fd857eeb9f
commit
3fa6a6b410
6 changed files with 358 additions and 92 deletions
|
@ -150,31 +150,31 @@ struct rtnl_link
|
|||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
char l_name[IFNAMSIZ];
|
||||
|
||||
uint32_t l_family;
|
||||
uint32_t l_arptype;
|
||||
uint32_t l_index;
|
||||
uint32_t l_flags;
|
||||
uint32_t l_change;
|
||||
uint32_t l_mtu;
|
||||
uint32_t l_link;
|
||||
uint32_t l_txqlen;
|
||||
uint32_t l_weight;
|
||||
uint32_t l_master;
|
||||
struct nl_addr *l_addr;
|
||||
struct nl_addr *l_bcast;
|
||||
char l_qdisc[IFQDISCSIZ];
|
||||
struct rtnl_link_map l_map;
|
||||
uint64_t l_stats[RTNL_LINK_STATS_MAX+1];
|
||||
uint32_t l_flag_mask;
|
||||
uint32_t l_num_vf;
|
||||
uint8_t l_operstate;
|
||||
uint8_t l_linkmode;
|
||||
char l_name[IFNAMSIZ];
|
||||
uint32_t l_family;
|
||||
uint32_t l_arptype;
|
||||
uint32_t l_index;
|
||||
uint32_t l_flags;
|
||||
uint32_t l_change;
|
||||
uint32_t l_mtu;
|
||||
uint32_t l_link;
|
||||
uint32_t l_txqlen;
|
||||
uint32_t l_weight;
|
||||
uint32_t l_master;
|
||||
struct nl_addr * l_addr;
|
||||
struct nl_addr * l_bcast;
|
||||
char l_qdisc[IFQDISCSIZ];
|
||||
struct rtnl_link_map l_map;
|
||||
uint64_t l_stats[RTNL_LINK_STATS_MAX+1];
|
||||
uint32_t l_flag_mask;
|
||||
uint32_t l_num_vf;
|
||||
uint8_t l_operstate;
|
||||
uint8_t l_linkmode;
|
||||
/* 2 byte hole */
|
||||
struct rtnl_link_info_ops *l_info_ops;
|
||||
void * l_info;
|
||||
char * l_ifalias;
|
||||
struct rtnl_link_info_ops * l_info_ops;
|
||||
void * l_af_data[AF_MAX];
|
||||
void * l_info;
|
||||
char * l_ifalias;
|
||||
};
|
||||
|
||||
struct rtnl_ncacheinfo
|
||||
|
|
115
include/netlink/route/link/api.h
Normal file
115
include/netlink/route/link/api.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* netlink/route/link/api.h Link Modules API
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LINK_API_H_
|
||||
#define NETLINK_LINK_API_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup link_info
|
||||
*
|
||||
* Link info operations
|
||||
*/
|
||||
struct rtnl_link_info_ops
|
||||
{
|
||||
/** Name of operations, must match name on kernel side */
|
||||
char * io_name;
|
||||
|
||||
/** Reference count (internal, do not use) */
|
||||
int io_refcnt;
|
||||
|
||||
/** Called to assign an info type to a link.
|
||||
* Has to allocate enough resources to hold attributes. Can
|
||||
* use link->l_info to store a pointer. */
|
||||
int (*io_alloc)(struct rtnl_link *);
|
||||
|
||||
/** Called to parse the link info attribute.
|
||||
* Must parse the attribute and assign all values to the link.
|
||||
*/
|
||||
int (*io_parse)(struct rtnl_link *,
|
||||
struct nlattr *,
|
||||
struct nlattr *);
|
||||
|
||||
/** Called when the link object is dumped.
|
||||
* Must dump the info type specific attributes. */
|
||||
void (*io_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
|
||||
struct nl_dump_params *);
|
||||
|
||||
/** Called when a link object is cloned.
|
||||
* Must clone all info type specific attributes. */
|
||||
int (*io_clone)(struct rtnl_link *, struct rtnl_link *);
|
||||
|
||||
/** Called when construction a link netlink message.
|
||||
* Must append all info type specific attributes to the message. */
|
||||
int (*io_put_attrs)(struct nl_msg *, struct rtnl_link *);
|
||||
|
||||
/** Called to release all resources previously allocated
|
||||
* in either io_alloc() or io_parse(). */
|
||||
void (*io_free)(struct rtnl_link *);
|
||||
|
||||
struct rtnl_link_info_ops * io_next;
|
||||
};
|
||||
|
||||
extern struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *);
|
||||
|
||||
extern int rtnl_link_register_info(struct rtnl_link_info_ops *);
|
||||
extern int rtnl_link_unregister_info(struct rtnl_link_info_ops *);
|
||||
|
||||
|
||||
struct rtnl_link_af_ops
|
||||
{
|
||||
/** The address family this operations set implements */
|
||||
const unsigned int ao_family;
|
||||
|
||||
/** Number of users of this operations, DO NOT MODIFY. */
|
||||
int ao_refcnt;
|
||||
|
||||
/** Validation policy for IFLA_PROTINFO attribute. This pointer
|
||||
* can be set to a nla_policy structure describing the minimal
|
||||
* requirements the attribute must meet. Failure of meeting these
|
||||
* requirements will result in a parsing error. */
|
||||
const struct nla_policy *ao_protinfo_policy;
|
||||
|
||||
/** Called after address family has been assigned to link. Must
|
||||
* allocate data buffer to hold address family specific data and
|
||||
* store it in link->l_af_data. */
|
||||
void * (*ao_alloc)(struct rtnl_link *);
|
||||
|
||||
/** Called when the link is cloned, must allocate a clone of the
|
||||
* address family specific buffer and return it. */
|
||||
void * (*ao_clone)(struct rtnl_link *, void *);
|
||||
|
||||
/** Called when the link gets freed. Must free all allocated data */
|
||||
void (*ao_free)(struct rtnl_link *, void *);
|
||||
|
||||
/** Called if a IFLA_PROTINFO attribute needs to be parsed. Typically
|
||||
* stores the parsed data in the address family specific buffer. */
|
||||
int (*ao_parse_protinfo)(struct rtnl_link *,
|
||||
struct nlattr *, void *);
|
||||
|
||||
/** Dump address family specific link attributes */
|
||||
void (*ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
|
||||
struct nl_dump_params *,
|
||||
void *);
|
||||
};
|
||||
|
||||
extern struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(unsigned int);
|
||||
extern void rtnl_link_af_ops_put(struct rtnl_link_af_ops *);
|
||||
extern int rtnl_link_af_register(struct rtnl_link_af_ops *);
|
||||
extern int rtnl_link_af_unregister(struct rtnl_link_af_ops *);
|
||||
|
||||
|
||||
#endif
|
|
@ -6,66 +6,15 @@
|
|||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LINK_INFO_API_H_
|
||||
#define NETLINK_LINK_INFO_API_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#warning "<netlink/route/link/info-api.h> is obsolete and may be removed in the future."
|
||||
#warning "include <netlink/route/link/api.h> instead.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup link_info
|
||||
*
|
||||
* Link info operations
|
||||
*/
|
||||
struct rtnl_link_info_ops
|
||||
{
|
||||
/** Name of operations, must match name on kernel side */
|
||||
char * io_name;
|
||||
|
||||
/** Reference count (internal, do not use) */
|
||||
int io_refcnt;
|
||||
|
||||
/** Called to assign an info type to a link.
|
||||
* Has to allocate enough resources to hold attributes. Can
|
||||
* use link->l_info to store a pointer. */
|
||||
int (*io_alloc)(struct rtnl_link *);
|
||||
|
||||
/** Called to parse the link info attribute.
|
||||
* Must parse the attribute and assign all values to the link.
|
||||
*/
|
||||
int (*io_parse)(struct rtnl_link *,
|
||||
struct nlattr *,
|
||||
struct nlattr *);
|
||||
|
||||
/** Called when the link object is dumped.
|
||||
* Must dump the info type specific attributes. */
|
||||
void (*io_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
|
||||
struct nl_dump_params *);
|
||||
|
||||
/** Called when a link object is cloned.
|
||||
* Must clone all info type specific attributes. */
|
||||
int (*io_clone)(struct rtnl_link *, struct rtnl_link *);
|
||||
|
||||
/** Called when construction a link netlink message.
|
||||
* Must append all info type specific attributes to the message. */
|
||||
int (*io_put_attrs)(struct nl_msg *, struct rtnl_link *);
|
||||
|
||||
/** Called to release all resources previously allocated
|
||||
* in either io_alloc() or io_parse(). */
|
||||
void (*io_free)(struct rtnl_link *);
|
||||
|
||||
struct rtnl_link_info_ops * io_next;
|
||||
};
|
||||
|
||||
extern struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *);
|
||||
|
||||
extern int rtnl_link_register_info(struct rtnl_link_info_ops *);
|
||||
extern int rtnl_link_unregister_info(struct rtnl_link_info_ops *);
|
||||
#include <netlink/route/link/api.h>
|
||||
|
||||
#endif
|
||||
|
|
130
lib/route/link.c
130
lib/route/link.c
|
@ -154,7 +154,7 @@
|
|||
#include <netlink/object.h>
|
||||
#include <netlink/route/rtnl.h>
|
||||
#include <netlink/route/link.h>
|
||||
#include <netlink/route/link/info-api.h>
|
||||
#include <netlink/route/link/api.h>
|
||||
|
||||
/** @cond SKIP */
|
||||
#define LINK_ATTR_MTU 0x0001
|
||||
|
@ -183,6 +183,84 @@ static struct nl_cache_ops rtnl_link_ops;
|
|||
static struct nl_object_ops link_obj_ops;
|
||||
/** @endcond */
|
||||
|
||||
static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
if (ops->ao_free)
|
||||
ops->ao_free(link, data);
|
||||
|
||||
rtnl_link_af_ops_put(ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_clone(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
struct rtnl_link *dst = arg;
|
||||
|
||||
if (ops->ao_clone &&
|
||||
!(dst->l_af_data[ops->ao_family] = ops->ao_clone(link, data)))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_dump_line(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
struct nl_dump_params *p = arg;
|
||||
|
||||
if (ops->ao_dump[NL_DUMP_LINE])
|
||||
ops->ao_dump[NL_DUMP_LINE](link, p, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_dump_details(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
struct nl_dump_params *p = arg;
|
||||
|
||||
if (ops->ao_dump[NL_DUMP_DETAILS])
|
||||
ops->ao_dump[NL_DUMP_DETAILS](link, p, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_dump_stats(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
struct nl_dump_params *p = arg;
|
||||
|
||||
if (ops->ao_dump[NL_DUMP_STATS])
|
||||
ops->ao_dump[NL_DUMP_STATS](link, p, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_foreach_af(struct rtnl_link *link,
|
||||
int (*cb)(struct rtnl_link *,
|
||||
struct rtnl_link_af_ops *, void *, void *),
|
||||
void *arg)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < AF_MAX; i++) {
|
||||
if (link->l_af_data[i]) {
|
||||
struct rtnl_link_af_ops *ops;
|
||||
|
||||
if (!(ops = rtnl_link_af_ops_lookup(i)))
|
||||
BUG();
|
||||
|
||||
if ((err = cb(link, ops, link->l_af_data[i], arg)) < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void release_link_info(struct rtnl_link *link)
|
||||
{
|
||||
struct rtnl_link_info_ops *io = link->l_info_ops;
|
||||
|
@ -208,6 +286,8 @@ static void link_free_data(struct nl_object *c)
|
|||
nl_addr_put(link->l_bcast);
|
||||
|
||||
free(link->l_ifalias);
|
||||
|
||||
do_foreach_af(link, af_free, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,6 +315,9 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
|
|||
return err;
|
||||
}
|
||||
|
||||
if ((err = do_foreach_af(src, af_clone, dst)) < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -270,6 +353,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
|||
struct rtnl_link *link;
|
||||
struct ifinfomsg *ifi;
|
||||
struct nlattr *tb[IFLA_MAX+1];
|
||||
struct rtnl_link_af_ops *af_ops = NULL;
|
||||
int err;
|
||||
|
||||
link = rtnl_link_alloc();
|
||||
|
@ -280,6 +364,27 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
|||
|
||||
link->ce_msgtype = n->nlmsg_type;
|
||||
|
||||
if (!nlmsg_valid_hdr(n, sizeof(*ifi)))
|
||||
return -NLE_MSG_TOOSHORT;
|
||||
|
||||
ifi = nlmsg_data(n);
|
||||
link->l_family = ifi->ifi_family;
|
||||
link->l_arptype = ifi->ifi_type;
|
||||
link->l_index = ifi->ifi_index;
|
||||
link->l_flags = ifi->ifi_flags;
|
||||
link->l_change = ifi->ifi_change;
|
||||
link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY |
|
||||
LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
|
||||
LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
|
||||
|
||||
if ((af_ops = rtnl_link_af_ops_lookup(ifi->ifi_family))) {
|
||||
if (af_ops->ao_protinfo_policy) {
|
||||
memcpy(&link_policy[IFLA_PROTINFO],
|
||||
af_ops->ao_protinfo_policy,
|
||||
sizeof(struct nla_policy));
|
||||
}
|
||||
}
|
||||
|
||||
err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, link_policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
@ -291,15 +396,6 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
|||
|
||||
nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ);
|
||||
|
||||
ifi = nlmsg_data(n);
|
||||
link->l_family = ifi->ifi_family;
|
||||
link->l_arptype = ifi->ifi_type;
|
||||
link->l_index = ifi->ifi_index;
|
||||
link->l_flags = ifi->ifi_flags;
|
||||
link->l_change = ifi->ifi_change;
|
||||
link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY |
|
||||
LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
|
||||
LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
|
||||
|
||||
if (tb[IFLA_STATS]) {
|
||||
struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]);
|
||||
|
@ -478,8 +574,16 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
|||
}
|
||||
}
|
||||
|
||||
if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) {
|
||||
err = af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
|
||||
link->l_af_data[link->l_family]);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = pp->pp_cb((struct nl_object *) link, pp);
|
||||
errout:
|
||||
rtnl_link_af_ops_put(af_ops);
|
||||
rtnl_link_put(link);
|
||||
return err;
|
||||
}
|
||||
|
@ -522,6 +626,8 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
|
|||
if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_LINE])
|
||||
link->l_info_ops->io_dump[NL_DUMP_LINE](link, p);
|
||||
|
||||
do_foreach_af(link, af_dump_line, p);
|
||||
|
||||
nl_dump(p, "\n");
|
||||
}
|
||||
|
||||
|
@ -570,6 +676,8 @@ static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p)
|
|||
|
||||
if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_DETAILS])
|
||||
link->l_info_ops->io_dump[NL_DUMP_DETAILS](link, p);
|
||||
|
||||
do_foreach_af(link, af_dump_details, p);
|
||||
}
|
||||
|
||||
static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
|
||||
|
@ -633,6 +741,8 @@ static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
|
|||
|
||||
if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_STATS])
|
||||
link->l_info_ops->io_dump[NL_DUMP_STATS](link, p);
|
||||
|
||||
do_foreach_af(link, af_dump_stats, p);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/route/link.h>
|
||||
#include <netlink/route/link/info-api.h>
|
||||
#include <netlink/route/link/api.h>
|
||||
|
||||
static struct rtnl_link_info_ops *info_ops;
|
||||
|
||||
|
@ -94,5 +94,97 @@ int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct rtnl_link_af_ops *af_ops[AF_MAX];
|
||||
|
||||
/**
|
||||
* Return operations of a specific link address family
|
||||
* @arg family Address family
|
||||
*
|
||||
* @note The returned pointer must be given back using rtnl_link_af_ops_put()
|
||||
*
|
||||
* @return Pointer to operations or NULL if unavailable.
|
||||
*/
|
||||
struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(const unsigned int family)
|
||||
{
|
||||
if (family == AF_UNSPEC || family >= AF_MAX)
|
||||
return NULL;
|
||||
|
||||
if (af_ops[family])
|
||||
af_ops[family]->ao_refcnt++;
|
||||
|
||||
return af_ops[family];
|
||||
}
|
||||
|
||||
/**
|
||||
* Give back reference to a set of operations.
|
||||
* @arg ops Address family operations.
|
||||
*/
|
||||
void rtnl_link_af_ops_put(struct rtnl_link_af_ops *ops)
|
||||
{
|
||||
ops->ao_refcnt--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register operations for a link address family
|
||||
* @arg ops Address family operations
|
||||
*
|
||||
* This function must be called by modules implementing a specific link
|
||||
* address family. It will make the operations implemented by the module
|
||||
* available for everyone else.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
* @return -NLE_INVAL Address family is out of range (0..AF_MAX)
|
||||
* @return -NLE_EXIST Operations for address family already registered.
|
||||
*/
|
||||
int rtnl_link_af_register(struct rtnl_link_af_ops *ops)
|
||||
{
|
||||
if (ops->ao_family == AF_UNSPEC || ops->ao_family >= AF_MAX)
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (af_ops[ops->ao_family])
|
||||
return -NLE_EXIST;
|
||||
|
||||
ops->ao_refcnt = 0;
|
||||
af_ops[ops->ao_family] = ops;
|
||||
|
||||
NL_DBG(1, "Registered link address family operations %u\n",
|
||||
ops->ao_family);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister operations for a link address family
|
||||
* @arg ops Address family operations
|
||||
*
|
||||
* This function must be called if a module implementing a specific link
|
||||
* address family is unloaded or becomes unavailable. It must provide a
|
||||
* set of operations which have previously been registered using
|
||||
* rtnl_link_af_register().
|
||||
*
|
||||
* @return 0 on success or a negative error code
|
||||
* @return -NLE_INVAL ops is NULL
|
||||
* @return -NLE_OBJ_NOTFOUND Address family operations not registered.
|
||||
* @return -NLE_BUSY Address family operations still in use.
|
||||
*/
|
||||
int rtnl_link_af_unregister(struct rtnl_link_af_ops *ops)
|
||||
{
|
||||
if (!ops)
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (!af_ops[ops->ao_family])
|
||||
return -NLE_OBJ_NOTFOUND;
|
||||
|
||||
if (ops->ao_refcnt > 0)
|
||||
return -NLE_BUSY;
|
||||
|
||||
af_ops[ops->ao_family] = NULL;
|
||||
|
||||
NL_DBG(1, "Unregistered link address family operations %u\n",
|
||||
ops->ao_family);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,7 @@
|
|||
#include <netlink/utils.h>
|
||||
#include <netlink/object.h>
|
||||
#include <netlink/route/rtnl.h>
|
||||
#include <netlink/route/link/info-api.h>
|
||||
#include <netlink/route/link/api.h>
|
||||
#include <netlink/route/link/vlan.h>
|
||||
|
||||
#include <linux/if_vlan.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue