summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-09-15 20:49:08 +0200
committerJo-Philipp Wich <jo@mein.io>2021-09-15 21:09:18 +0200
commitdd86e1dadab228c1a20bdb5504d216706cdd8624 (patch)
treea00d6f73947ee018c0757e093fa4464aa09f328b
parent74fdb97662fd3edfd52f7ff477e10490270c0d83 (diff)
rtnl: automatically derive message family from certain address attrs
# ucode -mrtnl -Rs 'printf("%.J", rtnl.request(rtnl.const.RTM_GETROUTE, 0, { dst: "8.8.8.8" }))' { "family": 2, "tos": 0, "protocol": 0, "scope": 0, "type": 1, "flags": 512, "dst": "8.8.8.8/32", "oif": "onboard", "gateway": "10.11.12.13", "prefsrc": "10.11.12.7", "cacheinfo": { "clntref": 2, "lastuse": 0, "expires": 0, "error": 0, "used": 0, "id": 0, "ts": 0, "tsage": 0 }, "table": 254, "uid": 0 } Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--lib/rtnl.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/lib/rtnl.c b/lib/rtnl.c
index 47e38db..2393264 100644
--- a/lib/rtnl.c
+++ b/lib/rtnl.c
@@ -461,6 +461,7 @@ enum {
DF_STORE_MASK = (1 << 8),
DF_MULTIPLE = (1 << 9),
DF_FLAT = (1 << 10),
+ DF_FAMILY_HINT = (1 << 11),
};
typedef struct uc_nl_attr_spec {
@@ -528,13 +529,13 @@ static const uc_nl_nested_spec_t route_msg = {
{ RTA_UNSPEC, "scope", DT_U8, 0, MEMBER(rtmsg, rtm_scope) },
{ RTA_UNSPEC, "type", DT_U8, 0, MEMBER(rtmsg, rtm_type) },
{ RTA_UNSPEC, "flags", DT_U32, 0, MEMBER(rtmsg, rtm_flags) },
- { RTA_SRC, "src", DT_ANYADDR, DF_STORE_MASK, MEMBER(rtmsg, rtm_src_len) },
- { RTA_DST, "dst", DT_ANYADDR, DF_STORE_MASK, MEMBER(rtmsg, rtm_dst_len) },
+ { RTA_SRC, "src", DT_ANYADDR, DF_STORE_MASK|DF_FAMILY_HINT, MEMBER(rtmsg, rtm_src_len) },
+ { RTA_DST, "dst", DT_ANYADDR, DF_STORE_MASK|DF_FAMILY_HINT, MEMBER(rtmsg, rtm_dst_len) },
{ RTA_IIF, "iif", DT_NETDEV, 0, NULL },
{ RTA_OIF, "oif", DT_NETDEV, 0, NULL },
- { RTA_GATEWAY, "gateway", DT_ANYADDR, 0, NULL },
+ { RTA_GATEWAY, "gateway", DT_ANYADDR, DF_FAMILY_HINT, NULL },
{ RTA_PRIORITY, "priority", DT_U32, 0, NULL },
- { RTA_PREFSRC, "prefsrc", DT_ANYADDR, 0, NULL },
+ { RTA_PREFSRC, "prefsrc", DT_ANYADDR, DF_FAMILY_HINT, NULL },
{ RTA_METRICS, "metrics", DT_NESTED, 0, &route_metrics_rta },
{ RTA_MULTIPATH, "multipath", DT_MULTIPATH, 0, NULL },
{ RTA_FLOW, "flow", DT_U32, 0, NULL },
@@ -1166,8 +1167,8 @@ static const uc_nl_nested_spec_t rule_msg = {
{ FRA_UNSPEC, "action", DT_U8, 0, MEMBER(fib_rule_hdr, action) },
{ FRA_UNSPEC, "flags", DT_U32, 0, MEMBER(fib_rule_hdr, flags) },
{ FRA_PRIORITY, "priority", DT_U32, 0, NULL },
- { FRA_SRC, "src", DT_ANYADDR, DF_STORE_MASK, MEMBER(fib_rule_hdr, src_len) },
- { FRA_DST, "dst", DT_ANYADDR, DF_STORE_MASK, MEMBER(fib_rule_hdr, dst_len) },
+ { FRA_SRC, "src", DT_ANYADDR, DF_STORE_MASK|DF_FAMILY_HINT, MEMBER(fib_rule_hdr, src_len) },
+ { FRA_DST, "dst", DT_ANYADDR, DF_STORE_MASK|DF_FAMILY_HINT, MEMBER(fib_rule_hdr, dst_len) },
{ FRA_FWMARK, "fwmark", DT_U32, 0, NULL },
{ FRA_FWMASK, "fwmask", DT_U32, 0, NULL },
{ FRA_IFNAME, "iif", DT_NETDEV, 0, NULL },
@@ -1181,7 +1182,7 @@ static const uc_nl_nested_spec_t rule_msg = {
{ FRA_SUPPRESS_PREFIXLEN, "suppress_prefixlen", DT_S32, 0, NULL },
{ FRA_SUPPRESS_IFGROUP, "suppress_ifgroup", DT_U32, 0, NULL },
{ FRA_FLOW, "flow", DT_U32, 0, NULL },
- { RTA_GATEWAY, "gateway", DT_ANYADDR, 0, NULL },
+ { RTA_GATEWAY, "gateway", DT_ANYADDR, DF_FAMILY_HINT, NULL },
{ FRA_GOTO, "goto", DT_U32, 0, NULL },
{ FRA_PROTOCOL, "protocol", DT_U8, 0, NULL },
}
@@ -2485,6 +2486,7 @@ uc_nl_parse_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base,
{
uc_nl_cidr_t cidr = { 0 };
struct ether_addr *ea;
+ struct rtgenmsg *rtg;
uint64_t u64;
uint32_t u32;
uint16_t u16;
@@ -2681,6 +2683,8 @@ uc_nl_parse_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base,
case DT_ANYADDR:
assert(spec->attr != 0);
+ rtg = nlmsg_data(nlmsg_hdr(msg));
+
if (!uc_nl_parse_cidr(vm, val, &cidr))
return nla_parse_error(spec, vm, val, "invalid IP address");
@@ -2696,6 +2700,9 @@ uc_nl_parse_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base,
nla_put(msg, attr, cidr.alen, &cidr.addr.in6);
+ if ((rtg->rtgen_family == AF_UNSPEC) && (spec->flags & DF_FAMILY_HINT))
+ rtg->rtgen_family = cidr.family;
+
break;
case DT_MULTIPATH: