diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-09-15 20:49:08 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-09-15 21:09:18 +0200 |
commit | dd86e1dadab228c1a20bdb5504d216706cdd8624 (patch) | |
tree | a00d6f73947ee018c0757e093fa4464aa09f328b | |
parent | 74fdb97662fd3edfd52f7ff477e10490270c0d83 (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.c | 21 |
1 files changed, 14 insertions, 7 deletions
@@ -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: |