From 430eb4004ab7f93fd840e9836d4bc9220d3c406d Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 7 May 2014 16:05:53 +0530 Subject: [PATCH] vlan: add support for IFLA_VLAN_PROTOCOL This patch adds support for IFLA_VLAN_PROTOCOL Signed-off-by: Susant Sahani Acked-by: Thomas Graf [thaller@redhat.com: minor fixes (whitespace, documentation, and a typo)] Signed-off-by: Thomas Haller --- include/linux/if_link.h | 1 + include/netlink/route/link/vlan.h | 3 ++ lib/route/link/vlan.c | 52 ++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 4a7cace..8b84939 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -244,6 +244,7 @@ enum { IFLA_VLAN_FLAGS, IFLA_VLAN_EGRESS_QOS, IFLA_VLAN_INGRESS_QOS, + IFLA_VLAN_PROTOCOL, __IFLA_VLAN_MAX, }; diff --git a/include/netlink/route/link/vlan.h b/include/netlink/route/link/vlan.h index f274163..4ec751e 100644 --- a/include/netlink/route/link/vlan.h +++ b/include/netlink/route/link/vlan.h @@ -34,6 +34,9 @@ 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_protocol(struct rtnl_link *link, uint16_t); +extern int rtnl_link_vlan_get_protocol(struct rtnl_link *link); + extern int rtnl_link_vlan_set_id(struct rtnl_link *, uint16_t); extern int rtnl_link_vlan_get_id(struct rtnl_link *); diff --git a/lib/route/link/vlan.c b/lib/route/link/vlan.c index 9bbe7d5..1a0d916 100644 --- a/lib/route/link/vlan.c +++ b/lib/route/link/vlan.c @@ -38,10 +38,12 @@ #define VLAN_HAS_FLAGS (1<<1) #define VLAN_HAS_INGRESS_QOS (1<<2) #define VLAN_HAS_EGRESS_QOS (1<<3) +#define VLAN_HAS_PROTOCOL (1<<4) struct vlan_info { uint16_t vi_vlan_id; + uint16_t vi_protocol; uint32_t vi_flags; uint32_t vi_flags_mask; uint32_t vi_ingress_qos[VLAN_PRIO_MAX+1]; @@ -58,6 +60,7 @@ static struct nla_policy vlan_policy[IFLA_VLAN_MAX+1] = { [IFLA_VLAN_FLAGS] = { .minlen = sizeof(struct ifla_vlan_flags) }, [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED }, [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED }, + [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 }, }; static int vlan_alloc(struct rtnl_link *link) @@ -94,6 +97,11 @@ static int vlan_parse(struct rtnl_link *link, struct nlattr *data, vi->vi_mask |= VLAN_HAS_ID; } + if (tb[IFLA_VLAN_PROTOCOL]) { + vi->vi_protocol = nla_get_u16(tb[IFLA_VLAN_PROTOCOL]); + vi->vi_mask |= VLAN_HAS_PROTOCOL; + } + if (tb[IFLA_VLAN_FLAGS]) { struct ifla_vlan_flags flags; nla_memcpy(&flags, tb[IFLA_VLAN_FLAGS], sizeof(flags)); @@ -186,7 +194,12 @@ static void vlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p) char buf[64]; rtnl_link_vlan_flags2str(vi->vi_flags, buf, sizeof(buf)); - nl_dump_line(p, " vlan-info id %d <%s>\n", vi->vi_vlan_id, buf); + nl_dump_line(p, " vlan-info id %d <%s>", vi->vi_vlan_id, buf); + + if (vi->vi_mask & VLAN_HAS_PROTOCOL) + nl_dump_line(p, " vlan protocol <%d>", vi->vi_protocol); + + nl_dump(p, "\n"); if (vi->vi_mask & VLAN_HAS_INGRESS_QOS) { nl_dump_line(p, @@ -409,6 +422,43 @@ int rtnl_link_vlan_get_id(struct rtnl_link *link) return 0; } +/** + * Set VLAN protocol + * @arg link Link object + * @arg protocol VLAN protocol + * + * @return 0 on success or a negative error code + */ +int rtnl_link_vlan_set_protocol(struct rtnl_link *link, uint16_t protocol) +{ + struct vlan_info *vi = link->l_info; + + IS_VLAN_LINK_ASSERT(link); + + vi->vi_protocol = protocol; + vi->vi_mask |= VLAN_HAS_PROTOCOL; + + return 0; +} + +/** + * Get VLAN protocol + * @arg link Link object + * + * @return VLAN protocol, 0 if not set or a negative error code. + */ +int rtnl_link_vlan_get_protocol(struct rtnl_link *link) +{ + struct vlan_info *vi = link->l_info; + + IS_VLAN_LINK_ASSERT(link); + + if (vi->vi_mask & VLAN_HAS_PROTOCOL) + return vi->vi_protocol; + else + return 0; +} + /** * Set VLAN flags * @arg link Link object -- 2.40.0