From 0c4b2ea6d17b3491b23f5ccb450176e05de75545 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 6 Dec 2016 12:02:54 +0100 Subject: [PATCH 1/4] link: add support for IFLA_CARRIER_CHANGES Also expose the attribute value via link_dump_details() Signed-off-by: Tobias Klauser --- include/netlink-private/types.h | 1 + include/netlink/route/link.h | 2 ++ lib/route/link.c | 32 ++++++++++++++++++++++++++++++-- libnl-route-3.sym | 1 + 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index a96c828..9089863 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -218,6 +218,7 @@ struct rtnl_link uint32_t l_group; uint8_t l_carrier; /* 3 byte hole */ + uint32_t l_carrier_changes; struct rtnl_link_af_ops * l_af_ops; struct nl_data * l_phys_port_id; int l_ns_fd; diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h index c0030ec..c1f353f 100644 --- a/include/netlink/route/link.h +++ b/include/netlink/route/link.h @@ -200,6 +200,8 @@ extern int rtnl_link_get_master(struct rtnl_link *); extern void rtnl_link_set_carrier(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_carrier(struct rtnl_link *); +extern int rtnl_link_get_carrier_changes(struct rtnl_link *, uint32_t *); + extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t); extern uint8_t rtnl_link_get_operstate(struct rtnl_link *); diff --git a/lib/route/link.c b/lib/route/link.c index 6a6e0d3..287b623 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -64,8 +64,9 @@ #define LINK_ATTR_NS_FD (1 << 29) #define LINK_ATTR_NS_PID (1 << 30) /* 31 used by 32-bit api */ -#define LINK_ATTR_LINK_NETNSID ((uint64_t) 1 << 32) -#define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33) +#define LINK_ATTR_LINK_NETNSID ((uint64_t) 1 << 32) +#define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33) +#define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; @@ -348,6 +349,7 @@ struct nla_policy rtln_link_policy[IFLA_MAX+1] = { [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, [IFLA_GROUP] = { .type = NLA_U32 }, [IFLA_CARRIER] = { .type = NLA_U8 }, + [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, [IFLA_PHYS_PORT_ID] = { .type = NLA_UNSPEC }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, [IFLA_NET_NS_FD] = { .type = NLA_U32 }, @@ -520,6 +522,11 @@ int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb) link->ce_mask |= LINK_ATTR_CARRIER; } + if (tb[IFLA_CARRIER_CHANGES]) { + link->l_carrier_changes = nla_get_u32(tb[IFLA_CARRIER_CHANGES]); + link->ce_mask |= LINK_ATTR_CARRIER_CHANGES; + } + if (tb[IFLA_OPERSTATE]) { link->l_operstate = nla_get_u8(tb[IFLA_OPERSTATE]); link->ce_mask |= LINK_ATTR_OPERSTATE; @@ -888,6 +895,9 @@ static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p) nl_dump(p, "carrier %s", rtnl_link_carrier2str(link->l_carrier, buf, sizeof(buf))); + if (link->ce_mask & LINK_ATTR_CARRIER_CHANGES) + nl_dump(p, " carrier-changes %u", link->l_carrier_changes); + nl_dump(p, "\n"); if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_DETAILS]) @@ -1117,6 +1127,7 @@ static const struct trans_tbl link_attrs[] = { __ADD(LINK_ATTR_NUM_RX_QUEUES, num_rx_queues), __ADD(LINK_ATTR_GROUP, group), __ADD(LINK_ATTR_CARRIER, carrier), + __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes), __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id), __ADD(LINK_ATTR_NS_FD, ns_fd), __ADD(LINK_ATTR_NS_PID, ns_pid), @@ -2272,6 +2283,23 @@ uint8_t rtnl_link_get_carrier(struct rtnl_link *link) return link->l_carrier; } +/** + * Return carrier on/off changes of link object + * @arg link Link object + * + * @return Carrier changes. + */ +int rtnl_link_get_carrier_changes(struct rtnl_link *link, uint32_t *carrier_changes) +{ + if (!(link->ce_mask & LINK_ATTR_CARRIER_CHANGES)) + return -NLE_NOATTR; + + if (carrier_changes) + *carrier_changes = link->l_carrier_changes; + + return 0; +} + /** * Set operational status of link object * @arg link Link object diff --git a/libnl-route-3.sym b/libnl-route-3.sym index f1a048c..b80c1f8 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -958,6 +958,7 @@ global: rtnl_link_bridge_set_hwmode; rtnl_link_bridge_hwmode2str; rtnl_link_bridge_str2hwmode; + rtnl_link_get_carrier_changes; rtnl_link_ipgre_get_pmtudisc; rtnl_link_is_ipgretap; rtnl_link_macvlan_add_macaddr; From 1eb0c1c8dc2c32197ed11b54b37e12ec550b200b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 6 Dec 2016 12:03:05 +0100 Subject: [PATCH 2/4] link: add support for IFLA_PHYS_PORT_NAME Signed-off-by: Tobias Klauser --- include/netlink-private/types.h | 1 + include/netlink/route/link.h | 2 ++ lib/route/link.c | 19 +++++++++++++++++++ libnl-route-3.sym | 1 + 4 files changed, 23 insertions(+) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 9089863..0bfdbd2 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -221,6 +221,7 @@ struct rtnl_link uint32_t l_carrier_changes; struct rtnl_link_af_ops * l_af_ops; struct nl_data * l_phys_port_id; + char l_phys_port_name[IFNAMSIZ]; int l_ns_fd; pid_t l_ns_pid; struct rtnl_link_vf * l_vf_list; diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h index c1f353f..09f9603 100644 --- a/include/netlink/route/link.h +++ b/include/netlink/route/link.h @@ -234,6 +234,8 @@ extern uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *); extern struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *); +extern char* rtnl_link_get_phys_port_name(struct rtnl_link *); + extern void rtnl_link_set_ns_fd(struct rtnl_link *, int); extern int rtnl_link_get_ns_fd(struct rtnl_link *); extern void rtnl_link_set_ns_pid(struct rtnl_link *, pid_t); diff --git a/lib/route/link.c b/lib/route/link.c index 287b623..6fd2546 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -67,6 +67,7 @@ #define LINK_ATTR_LINK_NETNSID ((uint64_t) 1 << 32) #define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33) #define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34) +#define LINK_ATTR_PHYS_PORT_NAME ((uint64_t) 1 << 35) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; @@ -351,6 +352,7 @@ struct nla_policy rtln_link_policy[IFLA_MAX+1] = { [IFLA_CARRIER] = { .type = NLA_U8 }, [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, [IFLA_PHYS_PORT_ID] = { .type = NLA_UNSPEC }, + [IFLA_PHYS_PORT_NAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, [IFLA_NET_NS_FD] = { .type = NLA_U32 }, }; @@ -736,6 +738,11 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, link->ce_mask |= LINK_ATTR_PHYS_PORT_ID; } + if (tb[IFLA_PHYS_PORT_NAME]) { + nla_strlcpy(link->l_phys_port_name, tb[IFLA_PHYS_PORT_NAME], IFNAMSIZ); + link->ce_mask |= LINK_ATTR_PHYS_PORT_NAME; + } + err = pp->pp_cb((struct nl_object *) link, pp); errout: rtnl_link_af_ops_put(af_ops); @@ -1129,6 +1136,7 @@ static const struct trans_tbl link_attrs[] = { __ADD(LINK_ATTR_CARRIER, carrier), __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes), __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id), + __ADD(LINK_ATTR_PHYS_PORT_NAME, phys_port_name), __ADD(LINK_ATTR_NS_FD, ns_fd), __ADD(LINK_ATTR_NS_PID, ns_pid), __ADD(LINK_ATTR_LINK_NETNSID, link_netnsid), @@ -2637,6 +2645,17 @@ struct nl_data *rtnl_link_get_phys_port_id(struct rtnl_link *link) return link->l_phys_port_id; } +/** + * Return physical port name of link object + * @arg link Link object + * + * @return Physical port name or NULL if not set. + */ +char *rtnl_link_get_phys_port_name(struct rtnl_link *link) +{ + return link->l_phys_port_name; +} + void rtnl_link_set_ns_fd(struct rtnl_link *link, int fd) { link->l_ns_fd = fd; diff --git a/libnl-route-3.sym b/libnl-route-3.sym index b80c1f8..d235c95 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -959,6 +959,7 @@ global: rtnl_link_bridge_hwmode2str; rtnl_link_bridge_str2hwmode; rtnl_link_get_carrier_changes; + rtnl_link_get_phys_port_name; rtnl_link_ipgre_get_pmtudisc; rtnl_link_is_ipgretap; rtnl_link_macvlan_add_macaddr; From 598e35dcd9c6cd7c2ee5bbfc1782c26106856376 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 6 Dec 2016 12:03:10 +0100 Subject: [PATCH 3/4] link: add support for IFLA_PHYS_SWITCH_ID Signed-off-by: Tobias Klauser --- include/netlink-private/types.h | 1 + include/netlink/route/link.h | 2 ++ lib/route/link.c | 28 ++++++++++++++++++++++++++++ libnl-route-3.sym | 1 + 4 files changed, 32 insertions(+) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 0bfdbd2..06eeb71 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -222,6 +222,7 @@ struct rtnl_link struct rtnl_link_af_ops * l_af_ops; struct nl_data * l_phys_port_id; char l_phys_port_name[IFNAMSIZ]; + struct nl_data * l_phys_switch_id; int l_ns_fd; pid_t l_ns_pid; struct rtnl_link_vf * l_vf_list; diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h index 09f9603..bf83b21 100644 --- a/include/netlink/route/link.h +++ b/include/netlink/route/link.h @@ -236,6 +236,8 @@ extern struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *); extern char* rtnl_link_get_phys_port_name(struct rtnl_link *); +extern struct nl_data * rtnl_link_get_phys_switch_id(struct rtnl_link *); + extern void rtnl_link_set_ns_fd(struct rtnl_link *, int); extern int rtnl_link_get_ns_fd(struct rtnl_link *); extern void rtnl_link_set_ns_pid(struct rtnl_link *, pid_t); diff --git a/lib/route/link.c b/lib/route/link.c index 6fd2546..599978a 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -68,6 +68,7 @@ #define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33) #define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34) #define LINK_ATTR_PHYS_PORT_NAME ((uint64_t) 1 << 35) +#define LINK_ATTR_PHYS_SWITCH_ID ((uint64_t) 1 << 36) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; @@ -277,6 +278,7 @@ static void link_free_data(struct nl_object *c) do_foreach_af(link, af_free, NULL); nl_data_free(link->l_phys_port_id); + nl_data_free(link->l_phys_switch_id); if (link->ce_mask & LINK_ATTR_VF_LIST) rtnl_link_sriov_free_data(link); @@ -318,6 +320,10 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src) if (!(dst->l_phys_port_id = nl_data_clone(src->l_phys_port_id))) return -NLE_NOMEM; + if (src->l_phys_switch_id) + if (!(dst->l_phys_switch_id = nl_data_clone(src->l_phys_switch_id))) + return -NLE_NOMEM; + if (src->ce_mask & LINK_ATTR_VF_LIST) if ((err = rtnl_link_sriov_clone(dst, src)) < 0) return err; @@ -353,6 +359,7 @@ struct nla_policy rtln_link_policy[IFLA_MAX+1] = { [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, [IFLA_PHYS_PORT_ID] = { .type = NLA_UNSPEC }, [IFLA_PHYS_PORT_NAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ }, + [IFLA_PHYS_SWITCH_ID] = { .type = NLA_UNSPEC }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, [IFLA_NET_NS_FD] = { .type = NLA_U32 }, }; @@ -743,6 +750,15 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, link->ce_mask |= LINK_ATTR_PHYS_PORT_NAME; } + if (tb[IFLA_PHYS_SWITCH_ID]) { + link->l_phys_switch_id = nl_data_alloc_attr(tb[IFLA_PHYS_SWITCH_ID]); + if (link->l_phys_switch_id == NULL) { + err = -NLE_NOMEM; + goto errout; + } + link->ce_mask |= LINK_ATTR_PHYS_SWITCH_ID; + } + err = pp->pp_cb((struct nl_object *) link, pp); errout: rtnl_link_af_ops_put(af_ops); @@ -1137,6 +1153,7 @@ static const struct trans_tbl link_attrs[] = { __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes), __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id), __ADD(LINK_ATTR_PHYS_PORT_NAME, phys_port_name), + __ADD(LINK_ATTR_PHYS_SWITCH_ID, phys_switch_id), __ADD(LINK_ATTR_NS_FD, ns_fd), __ADD(LINK_ATTR_NS_PID, ns_pid), __ADD(LINK_ATTR_LINK_NETNSID, link_netnsid), @@ -2656,6 +2673,17 @@ char *rtnl_link_get_phys_port_name(struct rtnl_link *link) return link->l_phys_port_name; } +/* + * Return physical switch id of link object + * @arg link Link object + * + * @return Physical switch id or NULL if not set. + */ +struct nl_data *rtnl_link_get_phys_switch_id(struct rtnl_link *link) +{ + return link->l_phys_switch_id; +} + void rtnl_link_set_ns_fd(struct rtnl_link *link, int fd) { link->l_ns_fd = fd; diff --git a/libnl-route-3.sym b/libnl-route-3.sym index d235c95..17be064 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -960,6 +960,7 @@ global: rtnl_link_bridge_str2hwmode; rtnl_link_get_carrier_changes; rtnl_link_get_phys_port_name; + rtnl_link_get_phys_switch_id; rtnl_link_ipgre_get_pmtudisc; rtnl_link_is_ipgretap; rtnl_link_macvlan_add_macaddr; From 6fc6bef6d045e1af47fd26470f746252e14a21c2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 6 Dec 2016 12:03:16 +0100 Subject: [PATCH 4/4] link: add support for IFLA_GSO_MAX_SEGS and IFLA_GSO_MAX_SIZE Signed-off-by: Tobias Klauser --- include/netlink-private/types.h | 2 ++ include/netlink/route/link.h | 4 +++ lib/route/link.c | 52 +++++++++++++++++++++++++++++++++ libnl-route-3.sym | 2 ++ 4 files changed, 60 insertions(+) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 06eeb71..4139619 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -215,6 +215,8 @@ struct rtnl_link uint32_t l_promiscuity; uint32_t l_num_tx_queues; uint32_t l_num_rx_queues; + uint32_t l_gso_max_segs; + uint32_t l_gso_max_size; uint32_t l_group; uint8_t l_carrier; /* 3 byte hole */ diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h index bf83b21..5f941d5 100644 --- a/include/netlink/route/link.h +++ b/include/netlink/route/link.h @@ -232,6 +232,10 @@ extern uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *); extern void rtnl_link_set_num_rx_queues(struct rtnl_link *, uint32_t); extern uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *); +extern int rtnl_link_get_gso_max_segs(struct rtnl_link *, uint32_t *); + +extern int rtnl_link_get_gso_max_size(struct rtnl_link *, uint32_t *); + extern struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *); extern char* rtnl_link_get_phys_port_name(struct rtnl_link *); diff --git a/lib/route/link.c b/lib/route/link.c index 599978a..f842810 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -69,6 +69,8 @@ #define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34) #define LINK_ATTR_PHYS_PORT_NAME ((uint64_t) 1 << 35) #define LINK_ATTR_PHYS_SWITCH_ID ((uint64_t) 1 << 36) +#define LINK_ATTR_GSO_MAX_SEGS ((uint64_t) 1 << 37) +#define LINK_ATTR_GSO_MAX_SIZE ((uint64_t) 1 << 38) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; @@ -354,6 +356,8 @@ struct nla_policy rtln_link_policy[IFLA_MAX+1] = { [IFLA_PROMISCUITY] = { .type = NLA_U32 }, [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 }, [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, + [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 }, + [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 }, [IFLA_GROUP] = { .type = NLA_U32 }, [IFLA_CARRIER] = { .type = NLA_U8 }, [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, @@ -731,6 +735,16 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES; } + if (tb[IFLA_GSO_MAX_SEGS]) { + link->l_gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); + link->ce_mask |= LINK_ATTR_GSO_MAX_SEGS; + } + + if (tb[IFLA_GSO_MAX_SIZE]) { + link->l_gso_max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]); + link->ce_mask |= LINK_ATTR_GSO_MAX_SIZE; + } + if (tb[IFLA_GROUP]) { link->l_group = nla_get_u32(tb[IFLA_GROUP]); link->ce_mask |= LINK_ATTR_GROUP; @@ -1148,6 +1162,8 @@ static const struct trans_tbl link_attrs[] = { __ADD(LINK_ATTR_PROMISCUITY, promiscuity), __ADD(LINK_ATTR_NUM_TX_QUEUES, num_tx_queues), __ADD(LINK_ATTR_NUM_RX_QUEUES, num_rx_queues), + __ADD(LINK_ATTR_GSO_MAX_SEGS, gso_max_segs), + __ADD(LINK_ATTR_GSO_MAX_SIZE, gso_max_size), __ADD(LINK_ATTR_GROUP, group), __ADD(LINK_ATTR_CARRIER, carrier), __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes), @@ -2651,6 +2667,42 @@ uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link) return link->l_num_rx_queues; } +/** + * Return maximum number of segments for generic segmentation offload + * @arg link Link object + * @arg gso_max_segs Pointer to store maximum number GSO segments + * + * @return 0 on success, negative error number otherwise + */ +int rtnl_link_get_gso_max_segs(struct rtnl_link *link, uint32_t *gso_max_segs) +{ + if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SEGS)) + return -NLE_NOATTR; + + if (gso_max_segs) + *gso_max_segs = link->l_gso_max_segs; + + return 0; +} + +/** + * Return maximum size for generic segmentation offload + * @arg link Link object + * @arg gso_max_segs Pointer to store maximum GSO size + * + * @return 0 on success, negative error number otherwise + */ +int rtnl_link_get_gso_max_size(struct rtnl_link *link, uint32_t *gso_max_size) +{ + if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SIZE)) + return -NLE_NOATTR; + + if (gso_max_size) + *gso_max_size = link->l_gso_max_size; + + return 0; +} + /** * Return physical port id of link object * @arg link Link object diff --git a/libnl-route-3.sym b/libnl-route-3.sym index 17be064..af1ed2d 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -959,6 +959,8 @@ global: rtnl_link_bridge_hwmode2str; rtnl_link_bridge_str2hwmode; rtnl_link_get_carrier_changes; + rtnl_link_get_gso_max_segs; + rtnl_link_get_gso_max_size; rtnl_link_get_phys_port_name; rtnl_link_get_phys_switch_id; rtnl_link_ipgre_get_pmtudisc;