forked from external/yambar
module: network: add 'kind' tag
The tag maps to the IFLA_INFO_KIND (part of the IFLA_LINKINFO) netlink attribute. This attribute is only available on virtual interfaces. Examples of valid values are: * bond * bridge * gre * tun * veth
This commit is contained in:
parent
a5ae61b5df
commit
699c563051
3 changed files with 93 additions and 48 deletions
|
@ -19,6 +19,7 @@
|
||||||
* Log output now respects the [`NO_COLOR`](http://no-color.org/)
|
* Log output now respects the [`NO_COLOR`](http://no-color.org/)
|
||||||
environment variable.
|
environment variable.
|
||||||
* network: `type` tag ([#380][380]).
|
* network: `type` tag ([#380][380]).
|
||||||
|
* network: `type` and `kind` tags ([#380][380]).
|
||||||
|
|
||||||
[96]: https://codeberg.org/dnkl/yambar/issues/96
|
[96]: https://codeberg.org/dnkl/yambar/issues/96
|
||||||
[380]: https://codeberg.org/dnkl/yambar/issues/380
|
[380]: https://codeberg.org/dnkl/yambar/issues/380
|
||||||
|
|
|
@ -25,6 +25,12 @@ address per network interface.
|
||||||
: string
|
: string
|
||||||
: Interface type (*ether*, *wlan*, *loopback*, or *ARPHRD_NNN*, where
|
: Interface type (*ether*, *wlan*, *loopback*, or *ARPHRD_NNN*, where
|
||||||
*N* is a number).
|
*N* is a number).
|
||||||
|
| kind
|
||||||
|
: string
|
||||||
|
: Interface kind. Empty for non-virtual interfaces. For virtual
|
||||||
|
interfaces, this value is taken from the _IFLA\_INFO\_KIND_ netlink
|
||||||
|
attribute. Examples of valid values are *bond*, *bridge*, *gre*, *tun*
|
||||||
|
and *veth*.
|
||||||
| index
|
| index
|
||||||
: int
|
: int
|
||||||
: Network interface index
|
: Network interface index
|
||||||
|
|
|
@ -53,7 +53,8 @@ struct af_addr {
|
||||||
|
|
||||||
struct iface {
|
struct iface {
|
||||||
char *name;
|
char *name;
|
||||||
char *type;
|
char *type; /* ARPHRD_NNN */
|
||||||
|
char *kind; /* IFLA_LINKINFO::IFLA_INFO_KIND */
|
||||||
|
|
||||||
uint32_t get_stats_seq_nr;
|
uint32_t get_stats_seq_nr;
|
||||||
|
|
||||||
|
@ -106,6 +107,7 @@ free_iface(struct iface iface)
|
||||||
{
|
{
|
||||||
tll_free(iface.addrs);
|
tll_free(iface.addrs);
|
||||||
free(iface.ssid);
|
free(iface.ssid);
|
||||||
|
free(iface.kind);
|
||||||
free(iface.type);
|
free(iface.type);
|
||||||
free(iface.name);
|
free(iface.name);
|
||||||
}
|
}
|
||||||
|
@ -211,6 +213,7 @@ content(struct module *mod)
|
||||||
.tags = (struct tag *[]){
|
.tags = (struct tag *[]){
|
||||||
tag_new_string(mod, "name", iface->name),
|
tag_new_string(mod, "name", iface->name),
|
||||||
tag_new_string(mod, "type", iface->type),
|
tag_new_string(mod, "type", iface->type),
|
||||||
|
tag_new_string(mod, "kind", iface->kind),
|
||||||
tag_new_int(mod, "index", iface->index),
|
tag_new_int(mod, "index", iface->index),
|
||||||
tag_new_bool(mod, "carrier", iface->carrier),
|
tag_new_bool(mod, "carrier", iface->carrier),
|
||||||
tag_new_string(mod, "state", state),
|
tag_new_string(mod, "state", state),
|
||||||
|
@ -225,7 +228,7 @@ content(struct module *mod)
|
||||||
tag_new_float(mod, "dl-speed", iface->dl_speed),
|
tag_new_float(mod, "dl-speed", iface->dl_speed),
|
||||||
tag_new_float(mod, "ul-speed", iface->ul_speed),
|
tag_new_float(mod, "ul-speed", iface->ul_speed),
|
||||||
},
|
},
|
||||||
.count = 15,
|
.count = 16,
|
||||||
};
|
};
|
||||||
exposables[idx++] = m->label->instantiate(m->label, &tags);
|
exposables[idx++] = m->label->instantiate(m->label, &tags);
|
||||||
tag_set_destroy(&tags);
|
tag_set_destroy(&tags);
|
||||||
|
@ -553,6 +556,78 @@ send_nl80211_get_scan(struct private *m)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len,
|
||||||
|
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||||
|
size_t len, void *ctx),
|
||||||
|
void *ctx)
|
||||||
|
{
|
||||||
|
const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN;
|
||||||
|
const uint8_t *end = (const uint8_t *)genl + len;
|
||||||
|
|
||||||
|
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
|
||||||
|
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
|
||||||
|
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
|
||||||
|
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
|
||||||
|
;
|
||||||
|
const void *payload = raw + NLA_HDRLEN;
|
||||||
|
|
||||||
|
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len,
|
||||||
|
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||||
|
const void *payload, size_t len, void *ctx),
|
||||||
|
void *ctx)
|
||||||
|
{
|
||||||
|
const uint8_t *raw = parent_payload;
|
||||||
|
const uint8_t *end = parent_payload + len;
|
||||||
|
|
||||||
|
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
|
||||||
|
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
|
||||||
|
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
|
||||||
|
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
|
||||||
|
const void *payload = raw + NLA_HDRLEN;
|
||||||
|
|
||||||
|
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_linkinfo(struct module *mod, struct iface *iface, uint16_t type,
|
||||||
|
bool nested, const void *payload, size_t len, void *_void)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case IFLA_INFO_KIND: {
|
||||||
|
const char *kind = payload;
|
||||||
|
free(iface->kind);
|
||||||
|
iface->kind = strndup(kind, len);
|
||||||
|
|
||||||
|
LOG_DBG("%s: IFLA_INFO_KIND: %s", iface->name, iface->kind);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IFLA_INFO_DATA:
|
||||||
|
//LOG_DBG("%s: IFLA_INFO_DATA", iface->name);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_WARN("unrecognized IFLA_LINKINFO attribute: "
|
||||||
|
"type=%hu, nested=%d, len=%zu",
|
||||||
|
type, nested, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len)
|
handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len)
|
||||||
|
@ -661,7 +736,8 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size
|
||||||
if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0)
|
if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", iface->name, mac[0], mac[1], mac[2], mac[3],
|
LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
iface->name, mac[0], mac[1], mac[2], mac[3],
|
||||||
mac[4], mac[5]);
|
mac[4], mac[5]);
|
||||||
|
|
||||||
mtx_lock(&mod->lock);
|
mtx_lock(&mod->lock);
|
||||||
|
@ -669,6 +745,13 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size
|
||||||
mtx_unlock(&mod->lock);
|
mtx_unlock(&mod->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case IFLA_LINKINFO: {
|
||||||
|
foreach_nlattr_nested(
|
||||||
|
mod, iface, RTA_DATA(attr), RTA_PAYLOAD(attr),
|
||||||
|
&parse_linkinfo, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,51 +834,6 @@ handle_address(struct module *mod, uint16_t type, const struct ifaddrmsg *msg, s
|
||||||
mod->bar->refresh(mod->bar);
|
mod->bar->refresh(mod->bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len,
|
|
||||||
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
|
||||||
size_t len, void *ctx),
|
|
||||||
void *ctx)
|
|
||||||
{
|
|
||||||
const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN;
|
|
||||||
const uint8_t *end = (const uint8_t *)genl + len;
|
|
||||||
|
|
||||||
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
|
|
||||||
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
|
|
||||||
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
|
|
||||||
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
|
|
||||||
;
|
|
||||||
const void *payload = raw + NLA_HDRLEN;
|
|
||||||
|
|
||||||
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len,
|
|
||||||
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
|
||||||
const void *payload, size_t len, void *ctx),
|
|
||||||
void *ctx)
|
|
||||||
{
|
|
||||||
const uint8_t *raw = parent_payload;
|
|
||||||
const uint8_t *end = parent_payload + len;
|
|
||||||
|
|
||||||
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
|
|
||||||
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
|
|
||||||
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
|
|
||||||
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
|
|
||||||
const void *payload = raw + NLA_HDRLEN;
|
|
||||||
|
|
||||||
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mcast_group {
|
struct mcast_group {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
Loading…
Add table
Reference in a new issue