summaryrefslogtreecommitdiff
path: root/src/platform/nm-linux-platform.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-02-14 13:08:12 +0100
committerThomas Haller <thaller@redhat.com>2019-03-04 14:28:19 +0100
commitf2deacc7aa13e8730c94471a973a0468af3daa11 (patch)
treed2733aa273c83c4ee714d691aadb0687aea00bd3 /src/platform/nm-linux-platform.c
parent169eb23299595fdb96445c8661ba4d6123298dbc (diff)
downloadNetworkManager-th/routing-rule.tar.gz
platform: add support for routing-ruleth/routing-rule
https://bugzilla.redhat.com/show_bug.cgi?id=1652653
Diffstat (limited to 'src/platform/nm-linux-platform.c')
-rw-r--r--src/platform/nm-linux-platform.c230
1 files changed, 219 insertions, 11 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index a4816d4197..c687758c9f 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -26,6 +26,7 @@
#include <endian.h>
#include <fcntl.h>
#include <libudev.h>
+#include <linux/fib_rules.h>
#include <linux/ip.h>
#include <linux/if_arp.h>
#include <linux/if_link.h>
@@ -291,8 +292,10 @@ typedef enum {
REFRESH_ALL_TYPE_IP6_ADDRESSES = 2,
REFRESH_ALL_TYPE_IP4_ROUTES = 3,
REFRESH_ALL_TYPE_IP6_ROUTES = 4,
- REFRESH_ALL_TYPE_QDISCS = 5,
- REFRESH_ALL_TYPE_TFILTERS = 6,
+ REFRESH_ALL_TYPE_ROUTING_RULES_IP4 = 5,
+ REFRESH_ALL_TYPE_ROUTING_RULES_IP6 = 6,
+ REFRESH_ALL_TYPE_QDISCS = 7,
+ REFRESH_ALL_TYPE_TFILTERS = 8,
_REFRESH_ALL_TYPE_NUM,
} RefreshAllType;
@@ -313,14 +316,16 @@ typedef enum {
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES = 1 << F (2, REFRESH_ALL_TYPE_IP6_ADDRESSES),
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES = 1 << F (3, REFRESH_ALL_TYPE_IP4_ROUTES),
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES = 1 << F (4, REFRESH_ALL_TYPE_IP6_ROUTES),
- DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS = 1 << F (5, REFRESH_ALL_TYPE_QDISCS),
- DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS = 1 << F (6, REFRESH_ALL_TYPE_TFILTERS),
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 = 1 << F (5, REFRESH_ALL_TYPE_ROUTING_RULES_IP4),
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6 = 1 << F (6, REFRESH_ALL_TYPE_ROUTING_RULES_IP6),
+ DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS = 1 << F (7, REFRESH_ALL_TYPE_QDISCS),
+ DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS = 1 << F (8, REFRESH_ALL_TYPE_TFILTERS),
#undef F
- DELAYED_ACTION_TYPE_REFRESH_LINK = 1 << 7,
- DELAYED_ACTION_TYPE_MASTER_CONNECTED = 1 << 8,
- DELAYED_ACTION_TYPE_READ_NETLINK = 1 << 9,
- DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE = 1 << 10,
+ DELAYED_ACTION_TYPE_REFRESH_LINK = 1 << 9,
+ DELAYED_ACTION_TYPE_MASTER_CONNECTED = 1 << 10,
+ DELAYED_ACTION_TYPE_READ_NETLINK = 1 << 11,
+ DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE = 1 << 12,
__DELAYED_ACTION_TYPE_MAX,
@@ -329,6 +334,8 @@ typedef enum {
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6 |
DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS |
DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS,
@@ -3353,6 +3360,166 @@ rta_multipath_done:
}
static NMPObject *
+_new_from_nl_routing_rule (struct nlmsghdr *nlh, gboolean id_only)
+{
+ static const struct nla_policy policy[] = {
+ [FRA_UNSPEC] = { },
+ [FRA_DST] = { /* struct in_addr, struct in6_addr */ },
+ [FRA_SRC] = { /* struct in_addr, struct in6_addr */ },
+ [FRA_IIFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ },
+ [FRA_GOTO] = { .type = NLA_U32 },
+ [FRA_UNUSED2] = { },
+ [FRA_PRIORITY] = { .type = NLA_U32 },
+ [FRA_UNUSED3] = { },
+ [FRA_UNUSED4] = { },
+ [FRA_UNUSED5] = { },
+ [FRA_FWMARK] = { .type = NLA_U32 },
+ [FRA_FLOW] = { .type = NLA_U32 },
+ [FRA_TUN_ID] = { .type = NLA_U64 },
+ [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 },
+ [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 },
+ [FRA_TABLE] = { .type = NLA_U32 },
+ [FRA_FWMASK] = { .type = NLA_U32 },
+ [FRA_OIFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ },
+ [FRA_PAD] = { .type = NLA_U32 },
+ [FRA_L3MDEV] = { .type = NLA_U8 },
+ [FRA_UID_RANGE] = { .minlen = sizeof(struct fib_rule_uid_range),
+ .maxlen = sizeof(struct fib_rule_uid_range) },
+ [FRA_PROTOCOL] = { .type = NLA_U8 },
+ [FRA_IP_PROTO] = { .type = NLA_U8 },
+ [FRA_SPORT_RANGE] = { .minlen = sizeof(struct fib_rule_port_range),
+ .maxlen = sizeof(struct fib_rule_port_range) },
+ [FRA_DPORT_RANGE] = { .minlen = sizeof(struct fib_rule_port_range),
+ .maxlen = sizeof(struct fib_rule_port_range) },
+ };
+ struct nlattr *tb[G_N_ELEMENTS (policy)];
+ const struct fib_rule_hdr *frh;
+ NMPlatformRoutingRule *props;
+ nm_auto_nmpobj NMPObject *obj = NULL;
+ int addr_family;
+ guint8 addr_size;
+
+ if (nlmsg_parse_arr (nlh, sizeof (*frh), tb, policy) < 0)
+ return NULL;
+
+ frh = nlmsg_data (nlh);
+
+ addr_family = frh->family;
+
+ if (!NM_IN_SET (addr_family, AF_INET, AF_INET6)) {
+ /* we don't care about other address families. */
+ return NULL;
+ }
+
+ addr_size = nm_utils_addr_family_to_size (addr_family);
+
+ obj = nmp_object_new (NMP_OBJECT_TYPE_ROUTING_RULE, NULL);
+ props = &obj->routing_rule;
+
+ props->addr_family = addr_family;
+ props->action = frh->action;
+ props->flags = frh->flags;
+ props->tos = frh->tos;
+
+ if (tb[FRA_TABLE])
+ props->table_coerced = nm_platform_route_table_coerce (nla_get_u32 (tb[FRA_TABLE]));
+ else
+ props->table_coerced = nm_platform_route_table_coerce (frh->table);
+
+ if (tb[FRA_SUPPRESS_PREFIXLEN])
+ props->suppress_prefixlen_inverse = ~nla_get_u32 (tb[FRA_SUPPRESS_PREFIXLEN]);
+
+ if (tb[FRA_SUPPRESS_IFGROUP])
+ props->suppress_ifgroup_inverse = ~nla_get_u32 (tb[FRA_SUPPRESS_IFGROUP]);
+
+ if (tb[FRA_IIFNAME])
+ nla_strlcpy (props->iifname, tb[FRA_IIFNAME], sizeof (props->iifname));
+
+ if (tb[FRA_OIFNAME])
+ nla_strlcpy (props->oifname, tb[FRA_OIFNAME], sizeof (props->oifname));
+
+ if (tb[FRA_PRIORITY])
+ props->priority = nla_get_u32 (tb[FRA_PRIORITY]);
+
+ if (tb[FRA_FWMARK])
+ props->fwmark = nla_get_u32 (tb[FRA_FWMARK]);
+
+ if (tb[FRA_FWMASK])
+ props->fwmask = nla_get_u32 (tb[FRA_FWMASK]);
+
+ if (tb[FRA_GOTO])
+ props->goto_target = nla_get_u32 (tb[FRA_GOTO]);
+
+ props->src_len = frh->src_len;
+ if (props->src_len > addr_size * 8)
+ return NULL;
+ if (!tb[FRA_SRC]) {
+ if (props->src_len > 0)
+ return NULL;
+ } else if (!nm_ip_addr_set_from_untrusted (addr_family,
+ &props->src,
+ nla_data (tb[FRA_SRC]),
+ nla_len (tb[FRA_SRC]),
+ NULL))
+ return NULL;
+
+ props->dst_len = frh->dst_len;
+ if (props->dst_len > addr_size * 8)
+ return NULL;
+ if (!tb[FRA_DST]) {
+ if (props->dst_len > 0)
+ return NULL;
+ } else if (!nm_ip_addr_set_from_untrusted (addr_family,
+ &props->dst,
+ nla_data (tb[FRA_DST]),
+ nla_len (tb[FRA_DST]),
+ NULL))
+ return NULL;
+
+ if (tb[FRA_FLOW])
+ props->flow = nla_get_u32 (tb[FRA_FLOW]);
+
+ if (tb[FRA_TUN_ID])
+ props->tun_id = nla_get_be64 (tb[FRA_TUN_ID]);
+
+ if (tb[FRA_L3MDEV]) {
+ /* actually, kernel only allows this attribute to be missing or
+ * "1". Still, encode it as full uint8.
+ *
+ * Note that FRA_L3MDEV and FRA_TABLE are mutally exclusive. */
+ props->l3mdev = nla_get_u8 (tb[FRA_L3MDEV]);
+ }
+
+ if (tb[FRA_PROTOCOL])
+ props->protocol = nla_get_u8 (tb[FRA_PROTOCOL]);
+ else
+ nm_assert (props->protocol == RTPROT_UNSPEC);
+
+ if (tb[FRA_IP_PROTO])
+ props->ip_proto = nla_get_u8 (tb[FRA_IP_PROTO]);
+
+ G_STATIC_ASSERT_EXPR (sizeof (NMFibRulePortRange) == sizeof (struct fib_rule_port_range));
+ G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMFibRulePortRange, start) == G_STRUCT_OFFSET (struct fib_rule_port_range, start));
+ G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMFibRulePortRange, end) == G_STRUCT_OFFSET (struct fib_rule_port_range, end));
+
+ nla_memcpy_checked_size (&props->sport_range, tb[FRA_SPORT_RANGE], sizeof (props->sport_range));
+ nla_memcpy_checked_size (&props->dport_range, tb[FRA_DPORT_RANGE], sizeof (props->dport_range));
+
+ if (tb[FRA_UID_RANGE]) {
+ const struct fib_rule_uid_range *r;
+
+ r = nla_data_as (struct fib_rule_uid_range, tb[FRA_UID_RANGE]);
+ props->uid_range = (NMFibRuleUidRange) {
+ .start = r->start,
+ .end = r->end,
+ };
+ props->uid_range_has = TRUE;
+ }
+
+ return g_steal_pointer (&obj);
+}
+
+static NMPObject *
_new_from_nl_qdisc (struct nlmsghdr *nlh, gboolean id_only)
{
static const struct nla_policy policy[] = {
@@ -3451,6 +3618,10 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m
case RTM_DELROUTE:
case RTM_GETROUTE:
return _new_from_nl_route (msghdr, id_only);
+ case RTM_NEWRULE:
+ case RTM_DELRULE:
+ case RTM_GETRULE:
+ return _new_from_nl_routing_rule (msghdr, id_only);
case RTM_NEWQDISC:
case RTM_DELQDISC:
case RTM_GETQDISC:
@@ -4370,6 +4541,8 @@ refresh_all_type_get_info (RefreshAllType refresh_all_type)
R (REFRESH_ALL_TYPE_IP6_ADDRESSES, NMP_OBJECT_TYPE_IP6_ADDRESS, AF_UNSPEC),
R (REFRESH_ALL_TYPE_IP4_ROUTES, NMP_OBJECT_TYPE_IP4_ROUTE, AF_UNSPEC),
R (REFRESH_ALL_TYPE_IP6_ROUTES, NMP_OBJECT_TYPE_IP6_ROUTE, AF_UNSPEC),
+ R (REFRESH_ALL_TYPE_ROUTING_RULES_IP4, NMP_OBJECT_TYPE_ROUTING_RULE, AF_INET),
+ R (REFRESH_ALL_TYPE_ROUTING_RULES_IP6, NMP_OBJECT_TYPE_ROUTING_RULE, AF_INET6),
R (REFRESH_ALL_TYPE_QDISCS, NMP_OBJECT_TYPE_QDISC, AF_UNSPEC),
R (REFRESH_ALL_TYPE_TFILTERS, NMP_OBJECT_TYPE_TFILTER, AF_UNSPEC),
#undef R
@@ -4389,6 +4562,8 @@ _NM_UTILS_LOOKUP_DEFINE (static, delayed_action_type_to_refresh_all_type, Delaye
NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, REFRESH_ALL_TYPE_IP6_ADDRESSES),
NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, REFRESH_ALL_TYPE_IP4_ROUTES),
NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, REFRESH_ALL_TYPE_IP6_ROUTES),
+ NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4, REFRESH_ALL_TYPE_ROUTING_RULES_IP4),
+ NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6, REFRESH_ALL_TYPE_ROUTING_RULES_IP6),
NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS, REFRESH_ALL_TYPE_QDISCS),
NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, REFRESH_ALL_TYPE_TFILTERS),
NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER (),
@@ -4419,6 +4594,13 @@ refresh_all_type_from_needle_object (const NMPObject *obj_needle)
case NMP_OBJECT_TYPE_IP6_ROUTE: return REFRESH_ALL_TYPE_IP6_ROUTES;
case NMP_OBJECT_TYPE_QDISC: return REFRESH_ALL_TYPE_QDISCS;
case NMP_OBJECT_TYPE_TFILTER: return REFRESH_ALL_TYPE_TFILTERS;
+ case NMP_OBJECT_TYPE_ROUTING_RULE:
+ switch (NMP_OBJECT_CAST_ROUTING_RULE (obj_needle)->addr_family) {
+ case AF_INET: return REFRESH_ALL_TYPE_ROUTING_RULES_IP4;
+ case AF_INET6: return REFRESH_ALL_TYPE_ROUTING_RULES_IP6;
+ }
+ nm_assert_not_reached ();
+ return 0;
default:
nm_assert_not_reached ();
return 0;
@@ -4426,12 +4608,23 @@ refresh_all_type_from_needle_object (const NMPObject *obj_needle)
}
static const NMPLookup *
-refresh_all_info_init_lookup (const RefreshAllInfo *refresh_all_info,
+refresh_all_type_init_lookup (RefreshAllType refresh_all_type,
NMPLookup *lookup)
{
+ const RefreshAllInfo *refresh_all_info;
+
nm_assert (lookup);
+
+ refresh_all_info = refresh_all_type_get_info (refresh_all_type);
+
nm_assert (refresh_all_info);
+ if (NM_IN_SET (refresh_all_info->obj_type, NMP_OBJECT_TYPE_ROUTING_RULE)) {
+ return nmp_lookup_init_object_by_addr_family (lookup,
+ refresh_all_info->obj_type,
+ refresh_all_info->addr_family);
+ }
+
/* not yet implemented. */
nm_assert (refresh_all_info->addr_family == AF_UNSPEC);
@@ -4452,6 +4645,8 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (delayed_action_to_string, DelayedActionType,
NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, "refresh-all-ip6-addresses"),
NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, "refresh-all-ip4-routes"),
NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, "refresh-all-ip6-routes"),
+ NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4, "refresh-all-routing-rules-ip4"),
+ NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6, "refresh-all-routing-rules-ip6"),
NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS, "refresh-all-qdiscs"),
NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, "refresh-all-tfilters"),
NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_LINK, "refresh-link"),
@@ -4864,7 +5059,7 @@ cache_prune_all (NMPlatform *platform)
priv->pruning[refresh_all_type] -= 1;
if (priv->pruning[refresh_all_type] > 0)
continue;
- refresh_all_info_init_lookup (refresh_all_type_get_info (refresh_all_type),
+ refresh_all_type_init_lookup (refresh_all_type,
&lookup);
cache_prune_one_type (platform, &lookup);
}
@@ -4938,6 +5133,8 @@ cache_on_change (NMPlatform *platform,
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6 |
DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS |
DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS,
NULL);
@@ -5296,6 +5493,7 @@ _nl_msg_new_dump (NMPObjectType obj_type,
case NMP_OBJECT_TYPE_IP6_ADDRESS:
case NMP_OBJECT_TYPE_IP4_ROUTE:
case NMP_OBJECT_TYPE_IP6_ROUTE:
+ case NMP_OBJECT_TYPE_ROUTING_RULE:
{
const struct rtgenmsg gmsg = {
.rtgen_family = preferred_addr_family,
@@ -5326,7 +5524,7 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio
NMPLookup lookup;
priv->pruning[refresh_all_type] += 1;
- refresh_all_info_init_lookup (refresh_all_type_get_info (refresh_all_type),
+ refresh_all_type_init_lookup (refresh_all_type,
&lookup);
nmp_cache_dirty_set_all (nm_platform_get_cache (platform),
&lookup);
@@ -5478,6 +5676,7 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event
if (NM_IN_SET (msghdr->nlmsg_type, RTM_DELLINK,
RTM_DELADDR,
RTM_DELROUTE,
+ RTM_DELRULE,
RTM_DELQDISC,
RTM_DELTFILTER)) {
/* The event notifies about a deleted object. We don't need to initialize all
@@ -5496,6 +5695,7 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event
&& NM_IN_SET (msghdr->nlmsg_type, RTM_NEWADDR,
RTM_NEWLINK,
RTM_NEWROUTE,
+ RTM_NEWRULE,
RTM_NEWQDISC,
RTM_NEWTFILTER)) {
is_dump = delayed_action_refresh_all_in_progress (platform,
@@ -5518,6 +5718,8 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event
case RTM_NEWLINK:
case RTM_NEWADDR:
case RTM_GETLINK:
+ case RTM_NEWRULE:
+ //XXX
case RTM_NEWQDISC:
case RTM_NEWTFILTER:
cache_op = nmp_cache_update_netlink (cache, obj, is_dump, &obj_old, &obj_new);
@@ -5616,6 +5818,8 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event
case RTM_DELLINK:
case RTM_DELADDR:
case RTM_DELROUTE:
+ case RTM_DELRULE:
+ //XXX
case RTM_DELQDISC:
case RTM_DELTFILTER:
cache_op = nmp_cache_remove_netlink (cache, obj, &obj_old, &obj_new);
@@ -8117,6 +8321,8 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks)
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6 |
DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS |
DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS,
NULL);
@@ -8411,6 +8617,8 @@ constructed (GObject *_object)
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 |
+ DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6 |
DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS |
DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS,
NULL);