From 8219cc79f827459192022c026f9d82d23ff1ab3b Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 21 Jul 2011 17:47:00 +0200 Subject: [PATCH] VLAN: rtnl_link_is_vlan() function and API documentation --- doc/route.txt | 1 + include/netlink/route/link/vlan.h | 6 +- lib/route/link/vlan.c | 131 +++++++++++++++++++++++------- 3 files changed, 106 insertions(+), 32 deletions(-) diff --git a/doc/route.txt b/doc/route.txt index b9b50b6..d48c26e 100644 --- a/doc/route.txt +++ b/doc/route.txt @@ -432,6 +432,7 @@ if (rtnl_link_add(sk, link, NLM_F_CREATE) < 0) rtnl_link_put(link); ----- +[[link_vlan]] ==== VLAN [source,c] diff --git a/include/netlink/route/link/vlan.h b/include/netlink/route/link/vlan.h index a3ad76d..42768b6 100644 --- a/include/netlink/route/link/vlan.h +++ b/include/netlink/route/link/vlan.h @@ -27,17 +27,19 @@ struct vlan_map #define VLAN_PRIO_MAX 7 +extern int rtnl_link_is_vlan(struct rtnl_link *); + extern char * rtnl_link_vlan_flags2str(int, char *, size_t); extern int rtnl_link_vlan_str2flags(const char *); -extern int rtnl_link_vlan_set_id(struct rtnl_link *, int); +extern int rtnl_link_vlan_set_id(struct rtnl_link *, uint16_t); extern int rtnl_link_vlan_get_id(struct rtnl_link *); extern int rtnl_link_vlan_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_vlan_unset_flags(struct rtnl_link *, unsigned int); -extern unsigned int rtnl_link_vlan_get_flags(struct rtnl_link *); +extern int rtnl_link_vlan_get_flags(struct rtnl_link *); extern int rtnl_link_vlan_set_ingress_map(struct rtnl_link *, int, uint32_t); diff --git a/lib/route/link/vlan.c b/lib/route/link/vlan.c index cbfdf34..cd831ce 100644 --- a/lib/route/link/vlan.c +++ b/lib/route/link/vlan.c @@ -12,7 +12,9 @@ /** * @ingroup link * @defgroup vlan VLAN - * @brief + * Virtual LAN link module + * + * See VLAN API documentation for more information * * @{ */ @@ -45,22 +47,9 @@ struct vlan_info struct vlan_map * vi_egress_qos; uint32_t vi_mask; }; + /** @endcond */ -static const struct trans_tbl vlan_flags[] = { - __ADD(VLAN_FLAG_REORDER_HDR, reorder_hdr) -}; - -char *rtnl_link_vlan_flags2str(int flags, char *buf, size_t len) -{ - return __flags2str(flags, buf, len, vlan_flags, ARRAY_SIZE(vlan_flags)); -} - -int rtnl_link_vlan_str2flags(const char *name) -{ - return __str2flags(name, vlan_flags, ARRAY_SIZE(vlan_flags)); -} - static struct nla_policy vlan_policy[IFLA_VLAN_MAX+1] = { [IFLA_VLAN_ID] = { .type = NLA_U16 }, [IFLA_VLAN_FLAGS] = { .minlen = sizeof(struct ifla_vlan_flags) }, @@ -241,7 +230,7 @@ static int vlan_clone(struct rtnl_link *dst, struct rtnl_link *src) int err; dst->l_info = NULL; - if ((err = rtnl_link_set_info_type(dst, "vlan")) < 0) + if ((err = rtnl_link_set_type(dst, "vlan")) < 0) return err; vdst = dst->l_info; @@ -334,12 +323,42 @@ static struct rtnl_link_info_ops vlan_info_ops = { .io_free = vlan_free, }; -int rtnl_link_vlan_set_id(struct rtnl_link *link, int id) +/** @cond SKIP */ +#define IS_VLAN_LINK_ASSERT(link) \ + if ((link)->l_info_ops != &vlan_info_ops) { \ + APPBUG("Link is not a vlan link. set type \"vlan\" first."); \ + return -NLE_OPNOTSUPP; \ + } +/** @endcond */ + +/** + * @name VLAN Object + * @{ + */ + +/** + * Check if link is a VLAN link + * @arg link Link object + * + * @return True if link is a VLAN link, otherwise false is returned. + */ +int rtnl_link_is_vlan(struct rtnl_link *link) +{ + return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vlan"); +} + +/** + * Set VLAN ID + * @arg link Link object + * @arg id VLAN identifier + * + * @return 0 on success or a negative error code + */ +int rtnl_link_vlan_set_id(struct rtnl_link *link, uint16_t id) { struct vlan_info *vi = link->l_info; - if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) - return -NLE_OPNOTSUPP; + IS_VLAN_LINK_ASSERT(link); vi->vi_vlan_id = id; vi->vi_mask |= VLAN_HAS_ID; @@ -347,12 +366,17 @@ int rtnl_link_vlan_set_id(struct rtnl_link *link, int id) return 0; } +/** + * Get VLAN Id + * @arg link Link object + * + * @return VLAN id, 0 if not set or a negative error code. + */ int rtnl_link_vlan_get_id(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; - if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) - return -NLE_OPNOTSUPP; + IS_VLAN_LINK_ASSERT(link); if (vi->vi_mask & VLAN_HAS_ID) return vi->vi_vlan_id; @@ -360,12 +384,18 @@ int rtnl_link_vlan_get_id(struct rtnl_link *link) return 0; } +/** + * Set VLAN flags + * @arg link Link object + * @arg flags VLAN flags + * + * @return 0 on success or a negative error code. + */ int rtnl_link_vlan_set_flags(struct rtnl_link *link, unsigned int flags) { struct vlan_info *vi = link->l_info; - if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) - return -NLE_OPNOTSUPP; + IS_VLAN_LINK_ASSERT(link); vi->vi_flags_mask |= flags; vi->vi_flags |= flags; @@ -374,12 +404,18 @@ int rtnl_link_vlan_set_flags(struct rtnl_link *link, unsigned int flags) return 0; } +/** + * Unset VLAN flags + * @arg link Link object + * @arg flags VLAN flags + * + * @return 0 on success or a negative error code. + */ int rtnl_link_vlan_unset_flags(struct rtnl_link *link, unsigned int flags) { struct vlan_info *vi = link->l_info; - if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) - return -NLE_OPNOTSUPP; + IS_VLAN_LINK_ASSERT(link); vi->vi_flags_mask |= flags; vi->vi_flags &= ~flags; @@ -388,23 +424,34 @@ int rtnl_link_vlan_unset_flags(struct rtnl_link *link, unsigned int flags) return 0; } -unsigned int rtnl_link_vlan_get_flags(struct rtnl_link *link) +/** + * Get VLAN flags + * @arg link Link object + * + * @return VLAN flags, 0 if none set, or a negative error code. + */ +int rtnl_link_vlan_get_flags(struct rtnl_link *link) { struct vlan_info *vi = link->l_info; - if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) - return -NLE_OPNOTSUPP; + IS_VLAN_LINK_ASSERT(link); return vi->vi_flags; } +/** @} */ + +/** + * @name Quality of Service + * @{ + */ + int rtnl_link_vlan_set_ingress_map(struct rtnl_link *link, int from, uint32_t to) { struct vlan_info *vi = link->l_info; - if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) - return -NLE_OPNOTSUPP; + IS_VLAN_LINK_ASSERT(link); if (from < 0 || from > VLAN_PRIO_MAX) return -NLE_INVAL; @@ -478,6 +525,30 @@ struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *link, } } +/** @} */ + +static const struct trans_tbl vlan_flags[] = { + __ADD(VLAN_FLAG_REORDER_HDR, reorder_hdr) +}; + +/** + * @name Flag Translation + * @{ + */ + +char *rtnl_link_vlan_flags2str(int flags, char *buf, size_t len) +{ + return __flags2str(flags, buf, len, vlan_flags, ARRAY_SIZE(vlan_flags)); +} + +int rtnl_link_vlan_str2flags(const char *name) +{ + return __str2flags(name, vlan_flags, ARRAY_SIZE(vlan_flags)); +} + +/** @} */ + + static void __init vlan_init(void) { rtnl_link_register_info(&vlan_info_ops);