siphash24_compress_typesafe(rule->suppress_ifgroup, state);
siphash24_compress_typesafe(rule->suppress_prefixlen, state);
siphash24_compress_typesafe(rule->fwmask, state);
- /* FRA_TUN_ID */
+ siphash24_compress_typesafe(rule->tunnel_id, state);
/* fr_net (network namespace) */
siphash24_compress_typesafe(rule->l3mdev, state);
siphash24_compress_typesafe(rule->uid_range, state);
siphash24_compress_typesafe(rule->from_prefixlen, state);
siphash24_compress_typesafe(rule->to_prefixlen, state);
siphash24_compress_typesafe(rule->tos, state);
- /* FRA_FLOW (IPv4 only) */
+ siphash24_compress_typesafe(rule->realms, state);
in_addr_hash_func(&rule->from, rule->family, state);
in_addr_hash_func(&rule->to, rule->family, state);
}
if (r != 0)
return r;
+ r = CMP(a->tunnel_id, b->tunnel_id);
+ if (r != 0)
+ return r;
+
r = CMP(a->l3mdev, b->l3mdev);
if (r != 0)
return r;
if (r != 0)
return r;
+ r = CMP(a->realms, b->realms);
+ if (r != 0)
+ return r;
+
if (all) {
r = memcmp(&a->from, &b->from, FAMILY_ADDRESS_SIZE(a->family));
if (r != 0)
if ((existing->flags ^ requesting->flags) & (FIB_RULE_PERMANENT|FIB_RULE_INVERT))
return false;
+ /* GOTO target cannot be updated. */
+ if (existing->type == FR_ACT_GOTO && existing->priority_goto != requesting->priority_goto)
+ return false;
+
return true;
}
if (r < 0)
return r;
+ if (rule->type == FR_ACT_GOTO) {
+ r = sd_netlink_message_append_u32(m, FRA_GOTO, rule->priority_goto);
+ if (r < 0)
+ return r;
+ }
+
+ if (rule->realms > 0) {
+ r = sd_netlink_message_append_u32(m, FRA_FLOW, rule->realms);
+ if (r < 0)
+ return r;
+ }
+
+ if (rule->tunnel_id > 0) {
+ r = sd_netlink_message_append_u64(m, FRA_TUN_ID, htobe64(rule->tunnel_id));
+ if (r < 0)
+ return r;
+ }
+
return 0;
}
if (r >= 0)
tmp->suppress_ifgroup = (int32_t) suppress_ifgroup;
+ r = sd_netlink_message_read_u64(message, FRA_TUN_ID, &tmp->tunnel_id);
+ if (r < 0 && r != -ENODATA) {
+ log_warning_errno(r, "rtnl: could not get FRA_TUN_ID attribute, ignoring: %m");
+ return 0;
+ }
+ if (r >= 0)
+ tmp->tunnel_id = be64toh(tmp->tunnel_id);
+
+ r = sd_netlink_message_read_u32(message, FRA_FLOW, &tmp->realms);
+ if (r < 0 && r != -ENODATA) {
+ log_warning_errno(r, "rtnl: could not get FRA_FLOW attribute, ignoring: %m");
+ return 0;
+ }
+
if (adjust_protocol)
/* As .network files does not have setting to specify protocol, we can assume the
* protocol of the received rule is RTPROT_KERNEL or RTPROT_STATIC. */
if (r < 0)
log_debug_errno(r, "rtnl: received rule message without valid flag, ignoring: %m");
+ r = sd_netlink_message_read_u32(message, FRA_GOTO, &rule->priority_goto);
+ if (r < 0 && r != -ENODATA)
+ log_debug_errno(r, "rtnl: could not get FRA_GOTO attribute, ignoring: %m");
+
routing_policy_rule_enter_configured(rule);
if (req)
routing_policy_rule_enter_configured(req->userdata);