diff options
Diffstat (limited to 'src/libnm-platform')
22 files changed, 2203 insertions, 1986 deletions
diff --git a/src/libnm-platform/meson.build b/src/libnm-platform/meson.build index 3e4f41a9..d0a7c6c2 100644 --- a/src/libnm-platform/meson.build +++ b/src/libnm-platform/meson.build @@ -9,7 +9,7 @@ libnm_platform = static_library( 'nm-platform.c', 'nmp-netns.c', 'nmp-object.c', - 'nmp-rules-manager.c', + 'nmp-route-manager.c', 'wifi/nm-wifi-utils-nl80211.c', 'wifi/nm-wifi-utils.c', 'wpan/nm-wpan-utils.c', diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 78df53e7..93935b98 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -402,11 +402,11 @@ typedef struct { guint32 seq_number; WaitForNlResponseResult seq_result; DelayedActionWaitForNlResponseType response_type; - gint64 timeout_abs_ns; - WaitForNlResponseResult * out_seq_result; - char ** out_errmsg; + gint64 timeout_abs_nsec; + WaitForNlResponseResult *out_seq_result; + char **out_errmsg; union { - int * out_refresh_all_in_progress; + int *out_refresh_all_in_progress; NMPObject **out_route_get; gpointer out_data; } response; @@ -446,11 +446,22 @@ typedef struct { GPtrArray *list_master_connected; GPtrArray *list_refresh_link; - GArray * list_wait_for_nl_response; + GArray *list_wait_for_nl_response; int is_handling; } delayed_action; + /* This is the receive buffer for netlink messages. This buffer should be large + * enough for any rtnetlink message. When too small, nl_recv() would notice the + * truncation and lose the message. In that case, we reallocate a larger buffer. + * + * We keep the receive buffer around for the entire lifetime of the platform instance. + * Usually we only have one platform instance per netns, so we don't waste too much. */ + struct { + unsigned char *buf; + gsize len; + } netlink_recv_buf; + } NMLinuxPlatformPrivate; struct _NMLinuxPlatform { @@ -493,7 +504,7 @@ NM_LINUX_PLATFORM_FROM_PRIVATE(NMLinuxPlatformPrivate *priv) G_STMT_START \ { \ char __prefix[32]; \ - const char * __p_prefix = _NMLOG_PREFIX_NAME; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ NMPlatform *const __self = (self); \ \ if (__self && nm_platform_get_log_with_ptr(__self)) { \ @@ -554,7 +565,7 @@ delayed_action_schedule(NMPlatform *platform, DelayedActionType action_type, gpo static gboolean delayed_action_handle_all(NMPlatform *platform, gboolean read_netlink); static void do_request_link_no_delayed_actions(NMPlatform *platform, int ifindex, const char *name); static void do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action_type); -static void cache_on_change(NMPlatform * platform, +static void cache_on_change(NMPlatform *platform, NMPCacheOpsType cache_op, const NMPObject *obj_old, const NMPObject *obj_new); @@ -576,8 +587,8 @@ wait_for_nl_response_to_nmerr(WaitForNlResponseResult seq_result) static const char * wait_for_nl_response_to_string(WaitForNlResponseResult seq_result, - const char * errmsg, - char * buf, + const char *errmsg, + char *buf, gsize buf_size) { char *buf0 = buf; @@ -993,9 +1004,9 @@ _addrtime_get_lifetimes(guint32 timestamp, /*****************************************************************************/ static const NMPObject * -_lookup_cached_link(const NMPCache * cache, +_lookup_cached_link(const NMPCache *cache, int ifindex, - gboolean * completed_from_cache, + gboolean *completed_from_cache, const NMPObject **link_cached) { const NMPObject *obj; @@ -1019,7 +1030,7 @@ static char * _linktype_read_devtype(int dirfd) { gs_free char *contents = NULL; - char * cont, *end; + char *cont, *end; nm_assert(dirfd >= 0); @@ -1046,16 +1057,16 @@ _linktype_read_devtype(int dirfd) } static NMLinkType -_linktype_get_type(NMPlatform * platform, - const NMPCache * cache, - const char * kind, +_linktype_get_type(NMPlatform *platform, + const NMPCache *cache, + const char *kind, int ifindex, - const char * ifname, + const char *ifname, unsigned flags, unsigned arptype, - gboolean * completed_from_cache, + gboolean *completed_from_cache, const NMPObject **link_cached, - const char ** out_kind) + const char **out_kind) { NMLinkType link_type; @@ -1138,7 +1149,7 @@ _linktype_get_type(NMPlatform * platform, { nm_auto_close int dirfd = -1; - gs_free char * devtype = NULL; + gs_free char *devtype = NULL; char ifname_verified[IFNAMSIZ]; dirfd = nmp_utils_sysctl_open_netdir(ifindex, ifname, ifname_verified); @@ -1242,12 +1253,12 @@ _nl_addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int al /* Copied and heavily modified from libnl3's inet6_parse_protinfo(). */ static gboolean -_parse_af_inet6(NMPlatform * platform, - struct nlattr * attr, +_parse_af_inet6(NMPlatform *platform, + struct nlattr *attr, NMUtilsIPv6IfaceId *out_token, - gboolean * out_token_valid, - guint8 * out_addr_gen_mode_inv, - gboolean * out_addr_gen_mode_valid) + gboolean *out_token_valid, + guint8 *out_addr_gen_mode_inv, + gboolean *out_addr_gen_mode_valid) { static const struct nla_policy policy[] = { [IFLA_INET6_FLAGS] = {.type = NLA_U32}, @@ -1258,7 +1269,7 @@ _parse_af_inet6(NMPlatform * platform, [IFLA_INET6_TOKEN] = {.minlen = sizeof(struct in6_addr)}, [IFLA_INET6_ADDR_GEN_MODE] = {.type = NLA_U8}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; + struct nlattr *tb[G_N_ELEMENTS(policy)]; struct in6_addr i6_token; gboolean token_valid = FALSE; gboolean addr_gen_mode_valid = FALSE; @@ -1331,8 +1342,8 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data) [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = {.type = NLA_U64}, }; NMPlatformLnkBridge *props; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; if (!info_data || !nm_streq0(kind, "bridge")) return NULL; @@ -1420,8 +1431,8 @@ _parse_lnk_gre(const char *kind, struct nlattr *info_data) [IFLA_GRE_TOS] = {.type = NLA_U8}, [IFLA_GRE_PMTUDISC] = {.type = NLA_U8}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkGre *props; gboolean is_tap; @@ -1480,10 +1491,10 @@ _parse_lnk_infiniband(const char *kind, struct nlattr *info_data) [IFLA_IPOIB_MODE] = {.type = NLA_U16}, [IFLA_IPOIB_UMCAST] = {.type = NLA_U16}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; + struct nlattr *tb[G_N_ELEMENTS(policy)]; NMPlatformLnkInfiniband *info; - NMPObject * obj; - const char * mode; + NMPObject *obj; + const char *mode; if (!info_data || !nm_streq0(kind, "ipoib")) return NULL; @@ -1529,8 +1540,8 @@ _parse_lnk_ip6tnl(const char *kind, struct nlattr *info_data) [IFLA_IPTUN_PROTO] = {.type = NLA_U8}, [IFLA_IPTUN_FLAGS] = {.type = NLA_U32}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkIp6Tnl *props; guint32 flowinfo; @@ -1582,8 +1593,8 @@ _parse_lnk_ip6gre(const char *kind, struct nlattr *info_data) [IFLA_GRE_FLOWINFO] = {.type = NLA_U32}, [IFLA_GRE_FLAGS] = {.type = NLA_U32}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkIp6Tnl *props; guint32 flowinfo; gboolean is_tap; @@ -1648,8 +1659,8 @@ _parse_lnk_ipip(const char *kind, struct nlattr *info_data) [IFLA_IPTUN_TOS] = {.type = NLA_U8}, [IFLA_IPTUN_PMTUDISC] = {.type = NLA_U8}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkIpIp *props; if (!info_data || !nm_streq0(kind, "ipip")) @@ -1681,8 +1692,8 @@ _parse_lnk_macvlan(const char *kind, struct nlattr *info_data) [IFLA_MACVLAN_FLAGS] = {.type = NLA_U16}, }; NMPlatformLnkMacvlan *props; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; gboolean tap; if (!info_data || !kind) @@ -1732,8 +1743,8 @@ _parse_lnk_macsec(const char *kind, struct nlattr *info_data) [IFLA_MACSEC_REPLAY_PROTECT] = {.type = NLA_U8}, [IFLA_MACSEC_VALIDATION] = {.type = NLA_U8}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkMacsec *props; if (!info_data || !nm_streq0(kind, "macsec")) @@ -1800,8 +1811,8 @@ _parse_lnk_sit(const char *kind, struct nlattr *info_data) [IFLA_IPTUN_FLAGS] = {.type = NLA_U16}, [IFLA_IPTUN_PROTO] = {.type = NLA_U8}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkSit *props; if (!info_data || !nm_streq0(kind, "sit")) @@ -1841,8 +1852,8 @@ _parse_lnk_tun(const char *kind, struct nlattr *info_data) [IFLA_TUN_NUM_QUEUES] = {.type = NLA_U32}, [IFLA_TUN_NUM_DISABLED_QUEUES] = {.type = NLA_U32}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; NMPlatformLnkTun *props; if (!info_data || !nm_streq0(kind, "tun")) @@ -1878,12 +1889,12 @@ _parse_lnk_tun(const char *kind, struct nlattr *info_data) /*****************************************************************************/ static gboolean -_vlan_qos_mapping_from_nla(struct nlattr * nlattr, +_vlan_qos_mapping_from_nla(struct nlattr *nlattr, const NMVlanQosMapping **out_map, - guint * out_n_map) + guint *out_n_map) { - struct nlattr * nla; - int remaining; + struct nlattr *nla; + int remaining; gs_unref_ptrarray GPtrArray *array = NULL; G_STATIC_ASSERT(sizeof(NMVlanQosMapping) == sizeof(struct ifla_vlan_qos_mapping)); @@ -1950,9 +1961,9 @@ _parse_lnk_vlan(const char *kind, struct nlattr *info_data) [IFLA_VLAN_EGRESS_QOS] = {.type = NLA_NESTED}, [IFLA_VLAN_PROTOCOL] = {.type = NLA_U16}, }; - struct nlattr *tb[G_N_ELEMENTS(policy)]; + struct nlattr *tb[G_N_ELEMENTS(policy)]; nm_auto_nmpobj NMPObject *obj = NULL; - NMPObject * obj_result; + NMPObject *obj_result; if (!info_data || !nm_streq0(kind, "vlan")) return NULL; @@ -2050,8 +2061,8 @@ _parse_lnk_vxlan(const char *kind, struct nlattr *info_data) [IFLA_VXLAN_PORT] = {.type = NLA_U16}, }; NMPlatformLnkVxlan *props; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; if (!info_data || !nm_streq0(kind, "vxlan")) return NULL; @@ -2117,8 +2128,8 @@ _parse_lnk_vrf(const char *kind, struct nlattr *info_data) [IFLA_VRF_TABLE] = {.type = NLA_U32}, }; NMPlatformLnkVrf *props; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; if (!info_data || !nm_streq0(kind, "vrf")) return NULL; @@ -2199,7 +2210,7 @@ _wireguard_update_from_peers_nla(CList *peers, GArray **p_allowed_ips, struct nl [WGPEER_A_TX_BYTES] = {.type = NLA_U64}, [WGPEER_A_ALLOWEDIPS] = {.type = NLA_NESTED}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; + struct nlattr *tb[G_N_ELEMENTS(policy)]; WireGuardPeerConstruct *peer_c; if (nla_parse_nested_arr(tb, peer_attr, policy) < 0) @@ -2259,7 +2270,7 @@ _wireguard_update_from_peers_nla(CList *peers, GArray **p_allowed_ips, struct nl if (tb[WGPEER_A_ALLOWEDIPS]) { struct nlattr *attr; int rem; - GArray * allowed_ips = *p_allowed_ips; + GArray *allowed_ips = *p_allowed_ips; nla_for_each_nested (attr, tb[WGPEER_A_ALLOWEDIPS], rem) { if (!allowed_ips) { @@ -2290,7 +2301,7 @@ typedef struct { const int ifindex; NMPObject *obj; CList peers; - GArray * allowed_ips; + GArray *allowed_ips; } WireGuardParseData; static int @@ -2306,7 +2317,7 @@ _wireguard_get_device_cb(struct nl_msg *msg, void *arg) [WGDEVICE_A_FWMARK] = {.type = NLA_U32}, [WGDEVICE_A_PEERS] = {.type = NLA_NESTED}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; + struct nlattr *tb[G_N_ELEMENTS(policy)]; WireGuardParseData *parse_data = arg; if (genlmsg_parse_arr(nlmsg_hdr(msg), 0, tb, policy) < 0) @@ -2327,7 +2338,7 @@ _wireguard_get_device_cb(struct nl_msg *msg, void *arg) /* we already have an object instance. This means the netlink message * is a continuation, only providing more WGDEVICE_A_PEERS data below. */ } else { - NMPObject * obj; + NMPObject *obj; NMPlatformLnkWireGuard *props; obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_WIREGUARD, NULL); @@ -2370,18 +2381,18 @@ _wireguard_get_device_cb(struct nl_msg *msg, void *arg) } static const NMPObject * -_wireguard_read_info(NMPlatform * platform /* used only as logging context */, +_wireguard_read_info(NMPlatform *platform /* used only as logging context */, struct nl_sock *genl, int wireguard_family_id, int ifindex) { nm_auto_nlmsg struct nl_msg *msg = NULL; - NMPObject * obj = NULL; - WireGuardPeerConstruct * peer_c; - WireGuardPeerConstruct * peer_c_safe; - gs_unref_array GArray *allowed_ips = NULL; - WireGuardParseData parse_data = { - .ifindex = ifindex, + NMPObject *obj = NULL; + WireGuardPeerConstruct *peer_c; + WireGuardPeerConstruct *peer_c_safe; + gs_unref_array GArray *allowed_ips = NULL; + WireGuardParseData parse_data = { + .ifindex = ifindex, }; guint i; @@ -2522,13 +2533,13 @@ _wireguard_get_family_id(NMPlatform *platform, int ifindex_try) static const NMPObject * _wireguard_refresh_link(NMPlatform *platform, int wireguard_family_id, int ifindex) { - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); nm_auto_nmpobj const NMPObject *obj_old = NULL; nm_auto_nmpobj const NMPObject *obj_new = NULL; nm_auto_nmpobj const NMPObject *lnk_new = NULL; NMPCacheOpsType cache_op; - const NMPObject * plink = NULL; - nm_auto_nmpobj NMPObject *obj = NULL; + const NMPObject *plink = NULL; + nm_auto_nmpobj NMPObject *obj = NULL; nm_assert(wireguard_family_id >= 0); nm_assert(ifindex > 0); @@ -2587,25 +2598,25 @@ _wireguard_refresh_link(NMPlatform *platform, int wireguard_family_id, int ifind } static int -_wireguard_create_change_nlmsgs(NMPlatform * platform, +_wireguard_create_change_nlmsgs(NMPlatform *platform, int ifindex, int wireguard_family_id, - const NMPlatformLnkWireGuard * lnk_wireguard, - const NMPWireGuardPeer * peers, + const NMPlatformLnkWireGuard *lnk_wireguard, + const NMPWireGuardPeer *peers, const NMPlatformWireGuardChangePeerFlags *peer_flags, guint peers_len, NMPlatformWireGuardChangeFlags change_flags, - GPtrArray ** out_msgs) + GPtrArray **out_msgs) { - gs_unref_ptrarray GPtrArray * msgs = NULL; - nm_auto_nlmsg struct nl_msg * msg = NULL; + gs_unref_ptrarray GPtrArray *msgs = NULL; + nm_auto_nlmsg struct nl_msg *msg = NULL; const guint IDX_NIL = G_MAXUINT; guint idx_peer_curr; guint idx_allowed_ips_curr; - struct nlattr * nest_peers; - struct nlattr * nest_curr_peer; - struct nlattr * nest_allowed_ips; - struct nlattr * nest_curr_allowed_ip; + struct nlattr *nest_peers; + struct nlattr *nest_curr_peer; + struct nlattr *nest_allowed_ips; + struct nlattr *nest_curr_allowed_ip; NMPlatformWireGuardChangePeerFlags p_flags = NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_DEFAULT; #define _nla_nest_end(msg, nest_start) \ @@ -2821,15 +2832,15 @@ nla_put_failure: } static int -link_wireguard_change(NMPlatform * platform, +link_wireguard_change(NMPlatform *platform, int ifindex, - const NMPlatformLnkWireGuard * lnk_wireguard, - const NMPWireGuardPeer * peers, + const NMPlatformLnkWireGuard *lnk_wireguard, + const NMPWireGuardPeer *peers, const NMPlatformWireGuardChangePeerFlags *peer_flags, guint peers_len, NMPlatformWireGuardChangeFlags change_flags) { - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); gs_unref_ptrarray GPtrArray *msgs = NULL; int wireguard_family_id; guint i; @@ -2897,8 +2908,8 @@ _nmp_link_address_set(NMPLinkAddress *dst, const struct nlattr *nla) /* Copied and heavily modified from libnl3's link_msg_parser(). */ static NMPObject * -_new_from_nl_link(NMPlatform * platform, - const NMPCache * cache, +_new_from_nl_link(NMPlatform *platform, + const NMPCache *cache, struct nlmsghdr *nlh, gboolean id_only) { @@ -2930,15 +2941,15 @@ _new_from_nl_link(NMPlatform * platform, [IFLA_LINK_NETNSID] = {}, [IFLA_PERM_ADDRESS] = {.type = NLA_UNSPEC}, }; - const struct ifinfomsg *ifi; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - struct nlattr * nl_info_data = NULL; - const char * nl_info_kind = NULL; + const struct ifinfomsg *ifi; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + struct nlattr *nl_info_data = NULL; + const char *nl_info_kind = NULL; nm_auto_nmpobj NMPObject *obj = NULL; gboolean completed_from_cache_val = FALSE; - gboolean * completed_from_cache = cache ? &completed_from_cache_val : NULL; - const NMPObject * link_cached = NULL; - const NMPObject * lnk_data = NULL; + gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL; + const NMPObject *link_cached = NULL; + const NMPObject *lnk_data = NULL; gboolean address_complete_from_cache = TRUE; gboolean perm_address_complete_from_cache = TRUE; gboolean broadcast_complete_from_cache = TRUE; @@ -3210,7 +3221,7 @@ _new_from_nl_link(NMPlatform * platform, if (obj->link.type == NM_LINK_TYPE_WIREGUARD) { const NMPObject *lnk_data_new = NULL; - struct nl_sock * genl = NM_LINUX_PLATFORM_GET_PRIVATE(platform)->genl; + struct nl_sock *genl = NM_LINUX_PLATFORM_GET_PRIVATE(platform)->genl; /* The WireGuard kernel module does not yet send link update * notifications, so we don't actually update the cache. For @@ -3255,9 +3266,9 @@ _new_from_nl_addr(struct nlmsghdr *nlh, gboolean id_only) [IFA_CACHEINFO] = {.minlen = nm_offsetofend(struct ifa_cacheinfo, tstamp)}, [IFA_FLAGS] = {}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - const struct ifaddrmsg *ifa; - gboolean is_v4; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + const struct ifaddrmsg *ifa; + gboolean IS_IPv4; nm_auto_nmpobj NMPObject *obj = NULL; int addr_len; guint32 lifetime, preferred, timestamp; @@ -3267,29 +3278,31 @@ _new_from_nl_addr(struct nlmsghdr *nlh, gboolean id_only) ifa = nlmsg_data(nlh); - if (!NM_IN_SET(ifa->ifa_family, AF_INET, AF_INET6)) + if (ifa->ifa_family == AF_INET) + IS_IPv4 = TRUE; + else if (ifa->ifa_family == AF_INET6) + IS_IPv4 = FALSE; + else return NULL; - is_v4 = ifa->ifa_family == AF_INET; - if (nlmsg_parse_arr(nlh, sizeof(*ifa), tb, policy) < 0) return NULL; - addr_len = is_v4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); + addr_len = IS_IPv4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); - if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128)) + if (ifa->ifa_prefixlen > (IS_IPv4 ? 32 : 128)) return NULL; /*****************************************************************/ - obj = nmp_object_new(is_v4 ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS, NULL); + obj = nmp_object_new(IS_IPv4 ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS, NULL); obj->ip_address.ifindex = ifa->ifa_index; obj->ip_address.plen = ifa->ifa_prefixlen; _check_addr_or_return_null(tb, IFA_ADDRESS, addr_len); _check_addr_or_return_null(tb, IFA_LOCAL, addr_len); - if (is_v4) { + if (IS_IPv4) { /* For IPv4, kernel omits IFA_LOCAL/IFA_ADDRESS if (and only if) they * are effectively 0.0.0.0 (all-zero). */ if (tb[IFA_LOCAL]) @@ -3325,7 +3338,7 @@ _new_from_nl_addr(struct nlmsghdr *nlh, gboolean id_only) obj->ip_address.n_ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifa->ifa_flags; - if (is_v4) { + if (IS_IPv4) { if (tb[IFA_LABEL]) { char label[IFNAMSIZ]; @@ -3374,9 +3387,9 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only) [RTA_METRICS] = {.type = NLA_NESTED}, [RTA_MULTIPATH] = {.type = NLA_NESTED}, }; - const struct rtmsg *rtm; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - gboolean is_v4; + const struct rtmsg *rtm; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + gboolean IS_IPv4; nm_auto_nmpobj NMPObject *obj = NULL; int addr_len; struct { @@ -3403,10 +3416,19 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only) * only handle ~supported~ routes. *****************************************************************/ - if (!NM_IN_SET(rtm->rtm_family, AF_INET, AF_INET6)) + if (rtm->rtm_family == AF_INET) + IS_IPv4 = TRUE; + else if (rtm->rtm_family == AF_INET6) + IS_IPv4 = FALSE; + else return NULL; - if (!NM_IN_SET(rtm->rtm_type, RTN_UNICAST, RTN_LOCAL)) + if (!NM_IN_SET(rtm->rtm_type, + RTN_UNICAST, + RTN_LOCAL, + RTN_BLACKHOLE, + RTN_UNREACHABLE, + RTN_PROHIBIT)) return NULL; if (nlmsg_parse_arr(nlh, sizeof(struct rtmsg), tb, policy) < 0) @@ -3414,10 +3436,9 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only) /*****************************************************************/ - is_v4 = rtm->rtm_family == AF_INET; - addr_len = is_v4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); + addr_len = IS_IPv4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); - if (rtm->rtm_dst_len > (is_v4 ? 32 : 128)) + if (rtm->rtm_dst_len > (IS_IPv4 ? 32 : 128)) return NULL; /***************************************************************** @@ -3481,16 +3502,45 @@ rta_multipath_done:; /* If no nexthops have been provided via RTA_MULTIPATH * we add it as regular nexthop to maintain backwards * compatibility */ - nh.ifindex = ifindex; - nh.gateway = gateway; + nh.ifindex = ifindex; + nh.gateway = gateway; + nh.is_present = TRUE; } else { /* Kernel supports new style nexthop configuration, * verify that it is a duplicate and ignore old-style nexthop. */ if (nh.ifindex != ifindex || memcmp(&nh.gateway, &gateway, addr_len) != 0) return NULL; } - } else if (!nh.is_present) - return NULL; + } + + if (nm_platform_route_type_is_nodev(rtm->rtm_type)) { + /* These routes are special. They don't have an device/ifindex. + * + * Well, actually, for IPv6 kernel will always say that the device is + * 1 (lo). Of course it does!! */ + if (nh.is_present) { + if (IS_IPv4) { + if (nh.ifindex != 0 || nh.gateway.addr4 != 0) { + /* we only accept kernel to notify about the ifindex/gateway, if it + * is zero. This is only to be a bit forgiving, but we really don't + * know how to handle such routes that have an ifindex. */ + return NULL; + } + } else { + if (!NM_IN_SET(nh.ifindex, 0, 1) || !IN6_IS_ADDR_UNSPECIFIED(&nh.gateway.addr6)) { + /* We allow an ifindex of 1 (will be normalized to zero). Otherwise, + * we don't expect a device/next hop. */ + return NULL; + } + nh.ifindex = 0; + } + } + } else { + if (!nh.is_present) { + /* a "normal" route needs a device. This is not the route we are looking for. */ + return NULL; + } + } /*****************************************************************/ @@ -3528,9 +3578,8 @@ rta_multipath_done:; /*****************************************************************/ - obj = nmp_object_new(is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE, NULL); + obj = nmp_object_new(IS_IPv4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE, NULL); - obj->ip_route.is_external = TRUE; obj->ip_route.type_coerced = nm_platform_route_type_coerce(rtm->rtm_type); obj->ip_route.table_coerced = nm_platform_route_table_coerce( tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : (guint32) rtm->rtm_table); @@ -3545,22 +3594,22 @@ rta_multipath_done:; if (tb[RTA_PRIORITY]) obj->ip_route.metric = nla_get_u32(tb[RTA_PRIORITY]); - if (is_v4) + if (IS_IPv4) obj->ip4_route.gateway = nh.gateway.addr4; else obj->ip6_route.gateway = nh.gateway.addr6; - if (is_v4) + if (IS_IPv4) obj->ip4_route.scope_inv = nm_platform_route_scope_inv(rtm->rtm_scope); if (_check_addr_or_return_null(tb, RTA_PREFSRC, addr_len)) { - if (is_v4) + if (IS_IPv4) memcpy(&obj->ip4_route.pref_src, nla_data(tb[RTA_PREFSRC]), addr_len); else memcpy(&obj->ip6_route.pref_src, nla_data(tb[RTA_PREFSRC]), addr_len); } - if (is_v4) + if (IS_IPv4) obj->ip4_route.tos = rtm->rtm_tos; else { if (tb[RTA_SRC]) { @@ -3582,7 +3631,7 @@ rta_multipath_done:; obj->ip_route.lock_initrwnd = NM_FLAGS_HAS(lock, 1 << RTAX_INITRWND); obj->ip_route.lock_mtu = NM_FLAGS_HAS(lock, 1 << RTAX_MTU); - if (!is_v4) { + if (!IS_IPv4) { if (tb[RTA_PREF]) obj->ip6_route.rt_pref = nla_get_u8(tb[RTA_PREF]); } @@ -3682,12 +3731,12 @@ _new_from_nl_routing_rule(struct nlmsghdr *nlh, gboolean id_only) .maxlen = sizeof(NMFibRulePortRange), }, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; + 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; + 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; @@ -3876,8 +3925,8 @@ _new_from_nl_qdisc(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_only) [TCA_KIND] = {.type = NLA_STRING}, [TCA_OPTIONS] = {.type = NLA_NESTED}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - const struct tcmsg *tcm; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + const struct tcmsg *tcm; nm_auto_nmpobj NMPObject *obj = NULL; if (!nm_platform_get_cache_tc(platform)) @@ -3926,7 +3975,7 @@ _new_from_nl_qdisc(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_only) [TCA_TBF_PARMS] = {.minlen = sizeof(struct tc_tbf_qopt)}, [TCA_TBF_RATE64] = {.type = NLA_U64}, }; - struct nlattr * tbf_tb[G_N_ELEMENTS(tbf_policy)]; + struct nlattr *tbf_tb[G_N_ELEMENTS(tbf_policy)]; struct tc_tbf_qopt opt; if (nla_parse_nested_arr(tbf_tb, tb[TCA_OPTIONS], tbf_policy) < 0) @@ -3988,8 +4037,8 @@ _new_from_nl_tfilter(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_onl static const struct nla_policy policy[] = { [TCA_KIND] = {.type = NLA_STRING}, }; - struct nlattr * tb[G_N_ELEMENTS(policy)]; - NMPObject * obj = NULL; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj = NULL; const struct tcmsg *tcm; if (!nm_platform_get_cache_tc(platform)) @@ -4028,9 +4077,9 @@ _new_from_nl_tfilter(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_onl * Returns: %NULL or a newly created NMPObject instance. **/ static NMPObject * -nmp_object_new_from_nl(NMPlatform * platform, +nmp_object_new_from_nl(NMPlatform *platform, const NMPCache *cache, - struct nl_msg * msg, + struct nl_msg *msg, gboolean id_only) { struct nlmsghdr *msghdr; @@ -4113,7 +4162,7 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo { struct nlattr *info; struct nlattr *data = NULL; - const char * kind; + const char *kind; nm_assert(msg); @@ -4242,9 +4291,9 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo } case NM_LINK_TYPE_VETH: { - const char * veth_peer = extra_data; + const char *veth_peer = extra_data; const struct ifinfomsg ifi = {}; - struct nlattr * info_peer; + struct nlattr *info_peer; nm_assert(veth_peer); @@ -4438,7 +4487,7 @@ nla_put_failure: } static gboolean -_nl_msg_new_link_set_linkinfo_vlan(struct nl_msg * msg, +_nl_msg_new_link_set_linkinfo_vlan(struct nl_msg *msg, int vlan_id, guint32 flags_mask, guint32 flags_set, @@ -4559,10 +4608,10 @@ _nl_msg_new_link_full(int nlmsg_type, { nm_auto_nlmsg struct nl_msg *msg = NULL; const struct ifinfomsg ifi = { - .ifi_family = family, - .ifi_change = flags_mask, - .ifi_flags = flags_set, - .ifi_index = ifindex, + .ifi_family = family, + .ifi_change = flags_mask, + .ifi_flags = flags_set, + .ifi_index = ifindex, }; nm_assert(NM_IN_SET(nlmsg_type, RTM_DELLINK, RTM_NEWLINK, RTM_GETLINK, RTM_SETLINK)); @@ -4601,14 +4650,14 @@ _nl_msg_new_address(int nlmsg_type, guint32 lifetime, guint32 preferred, in_addr_t ip4_broadcast_address, - const char * label) + const char *label) { nm_auto_nlmsg struct nl_msg *msg = NULL; struct ifaddrmsg am = { - .ifa_family = family, - .ifa_index = ifindex, - .ifa_prefixlen = plen, - .ifa_flags = flags, + .ifa_family = family, + .ifa_index = ifindex, + .ifa_prefixlen = plen, + .ifa_flags = flags, }; gsize addr_len; @@ -4680,27 +4729,48 @@ ip_route_get_lock_flag(const NMPlatformIPRoute *route) | (((guint32) route->lock_mtu) << RTAX_MTU); } +static gboolean +ip_route_ignored_protocol(const NMPlatformIPRoute *route) +{ + guint8 prot; + + nm_assert(route); + nm_assert(route->rt_source >= NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC + && route->rt_source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST); + + prot = route->rt_source - 1; + + nm_assert(nmp_utils_ip_config_source_from_rtprot(prot) == route->rt_source); + + /* We ignore all routes outside a certain subest of rtm_protocol. NetworkManager + * itself wouldn't configure those, so they are always configured by somebody + * external. We thus ignore them to avoid the overhead that processing them brings. + * For example, the BGP daemon "bird" might configure a huge number of RTPROT_BIRD routes. */ + + return prot > RTPROT_STATIC && !NM_IN_SET(prot, RTPROT_DHCP, RTPROT_RA); +} + /* Copied and modified from libnl3's build_route_msg() and rtnl_route_build_msg(). */ static struct nl_msg * _nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) { - nm_auto_nlmsg struct nl_msg *msg = NULL; - const NMPClass * klass = NMP_OBJECT_GET_CLASS(obj); - gboolean is_v4 = klass->addr_family == AF_INET; - const guint32 lock = ip_route_get_lock_flag(NMP_OBJECT_CAST_IP_ROUTE(obj)); + nm_auto_nlmsg struct nl_msg *msg = NULL; + const NMPClass *klass = NMP_OBJECT_GET_CLASS(obj); + const gboolean IS_IPv4 = NM_IS_IPv4(klass->addr_family); + const guint32 lock = ip_route_get_lock_flag(NMP_OBJECT_CAST_IP_ROUTE(obj)); const guint32 table = nm_platform_route_table_uncoerce(NMP_OBJECT_CAST_IP_ROUTE(obj)->table_coerced, TRUE); const struct rtmsg rtmsg = { .rtm_family = klass->addr_family, - .rtm_tos = is_v4 ? obj->ip4_route.tos : 0, + .rtm_tos = IS_IPv4 ? obj->ip4_route.tos : 0, .rtm_table = table <= 0xFF ? table : RT_TABLE_UNSPEC, .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot(obj->ip_route.rt_source), .rtm_scope = - is_v4 ? nm_platform_route_scope_inv(obj->ip4_route.scope_inv) : RT_SCOPE_NOWHERE, + IS_IPv4 ? nm_platform_route_scope_inv(obj->ip4_route.scope_inv) : RT_SCOPE_NOWHERE, .rtm_type = nm_platform_route_type_uncoerce(NMP_OBJECT_CAST_IP_ROUTE(obj)->type_coerced), .rtm_flags = obj->ip_route.r_rtm_flags & ((unsigned) (RTNH_F_ONLINK)), .rtm_dst_len = obj->ip_route.plen, - .rtm_src_len = is_v4 ? 0 : NMP_OBJECT_CAST_IP6_ROUTE(obj)->src_plen, + .rtm_src_len = IS_IPv4 ? 0 : NMP_OBJECT_CAST_IP6_ROUTE(obj)->src_plen, }; gsize addr_len; @@ -4714,28 +4784,28 @@ _nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) if (nlmsg_append_struct(msg, &rtmsg) < 0) goto nla_put_failure; - addr_len = is_v4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); + addr_len = IS_IPv4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); NLA_PUT(msg, RTA_DST, addr_len, - is_v4 ? (gconstpointer) &obj->ip4_route.network - : (gconstpointer) &obj->ip6_route.network); + IS_IPv4 ? (gconstpointer) &obj->ip4_route.network + : (gconstpointer) &obj->ip6_route.network); - if (!is_v4) { + if (!IS_IPv4) { if (!IN6_IS_ADDR_UNSPECIFIED(&NMP_OBJECT_CAST_IP6_ROUTE(obj)->src)) NLA_PUT(msg, RTA_SRC, addr_len, &obj->ip6_route.src); } NLA_PUT_U32(msg, RTA_PRIORITY, - is_v4 ? nm_platform_ip4_route_get_effective_metric(&obj->ip4_route) - : nm_platform_ip6_route_get_effective_metric(&obj->ip6_route)); + IS_IPv4 ? nm_platform_ip4_route_get_effective_metric(&obj->ip4_route) + : nm_platform_ip6_route_get_effective_metric(&obj->ip6_route)); if (table > 0xFF) NLA_PUT_U32(msg, RTA_TABLE, table); - if (is_v4) { + if (IS_IPv4) { if (NMP_OBJECT_CAST_IP4_ROUTE(obj)->pref_src) NLA_PUT(msg, RTA_PREFSRC, addr_len, &obj->ip4_route.pref_src); } else { @@ -4770,7 +4840,7 @@ _nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) } /* We currently don't have need for multi-hop routes... */ - if (is_v4) { + if (IS_IPv4) { NLA_PUT(msg, RTA_GATEWAY, addr_len, &obj->ip4_route.gateway); } else { if (!IN6_IS_ADDR_UNSPECIFIED(&obj->ip6_route.gateway)) @@ -4778,7 +4848,7 @@ _nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) } NLA_PUT_U32(msg, RTA_OIF, obj->ip_route.ifindex); - if (!is_v4 && obj->ip6_route.rt_pref != NM_ICMPV6_ROUTER_PREF_MEDIUM) + if (!IS_IPv4 && obj->ip6_route.rt_pref != NM_ICMPV6_ROUTER_PREF_MEDIUM) NLA_PUT_U8(msg, RTA_PREF, obj->ip6_route.rt_pref); return g_steal_pointer(&msg); @@ -4904,13 +4974,13 @@ static struct nl_msg * _nl_msg_new_qdisc(int nlmsg_type, int nlmsg_flags, const NMPlatformQdisc *qdisc) { nm_auto_nlmsg struct nl_msg *msg = NULL; - struct nlattr * tc_options; + struct nlattr *tc_options; const struct tcmsg tcm = { - .tcm_family = qdisc->addr_family, - .tcm_ifindex = qdisc->ifindex, - .tcm_handle = qdisc->handle, - .tcm_parent = qdisc->parent, - .tcm_info = qdisc->info, + .tcm_family = qdisc->addr_family, + .tcm_ifindex = qdisc->ifindex, + .tcm_handle = qdisc->handle, + .tcm_parent = qdisc->parent, + .tcm_info = qdisc->info, }; msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags | NMP_NLM_FLAG_F_ECHO); @@ -4991,14 +5061,14 @@ static struct nl_msg * _nl_msg_new_tfilter(int nlmsg_type, int nlmsg_flags, const NMPlatformTfilter *tfilter) { nm_auto_nlmsg struct nl_msg *msg = NULL; - struct nlattr * tc_options; - struct nlattr * act_tab; + struct nlattr *tc_options; + struct nlattr *act_tab; const struct tcmsg tcm = { - .tcm_family = tfilter->addr_family, - .tcm_ifindex = tfilter->ifindex, - .tcm_handle = tfilter->handle, - .tcm_parent = tfilter->parent, - .tcm_info = tfilter->info, + .tcm_family = tfilter->addr_family, + .tcm_ifindex = tfilter->ifindex, + .tcm_handle = tfilter->handle, + .tcm_parent = tfilter->parent, + .tcm_info = tfilter->info, }; msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags | NMP_NLM_FLAG_F_ECHO); @@ -5016,8 +5086,8 @@ _nl_msg_new_tfilter(int nlmsg_type, int nlmsg_flags, const NMPlatformTfilter *tf if (tfilter->action.kind) { const NMPlatformAction *action = &tfilter->action; - struct nlattr * prio; - struct nlattr * act_options; + struct nlattr *prio; + struct nlattr *act_options; if (!(prio = nla_nest_start(msg, 1 /* priority */))) goto nla_put_failure; @@ -5121,7 +5191,7 @@ _log_dbg_sysctl_set_impl(NMPlatform *platform, const char *path, const char *value) { - GError * error = NULL; + GError *error = NULL; gs_free char *contents = NULL; gs_free char *value_escaped = g_strescape(value, NULL); @@ -5175,7 +5245,7 @@ sysctl_set_internal(NMPlatform *platform, int fd, tries; gssize nwrote; gssize len; - char * actual; + char *actual; gs_free char *actual_free = NULL; int errsv; @@ -5314,12 +5384,12 @@ sysctl_set(NMPlatform *platform, const char *pathid, int dirfd, const char *path } typedef struct { - NMPlatform * platform; - char * pathid; + NMPlatform *platform; + char *pathid; int dirfd; - char * path; - char ** values; - GCancellable * cancellable; + char *path; + char **values; + GCancellable *cancellable; NMPlatformAsyncCallback callback; gpointer callback_data; } SysctlAsyncInfo; @@ -5340,11 +5410,11 @@ sysctl_async_info_free(SysctlAsyncInfo *info) static void sysctl_async_cb(GObject *object, GAsyncResult *res, gpointer user_data) { - NMPlatform * platform; - GTask * task = G_TASK(res); - SysctlAsyncInfo *info; + NMPlatform *platform; + GTask *task = G_TASK(res); + SysctlAsyncInfo *info; gs_free_error GError *error = NULL; - gs_free char * values_str = NULL; + gs_free char *values_str = NULL; info = g_task_get_task_data(task); @@ -5360,15 +5430,15 @@ sysctl_async_cb(GObject *object, GAsyncResult *res, gpointer user_data) } static void -sysctl_async_thread_fn(GTask * task, +sysctl_async_thread_fn(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { nm_auto_pop_netns NMPNetns *netns = NULL; - SysctlAsyncInfo * info = task_data; - GError * error = NULL; - char ** value; + SysctlAsyncInfo *info = task_data; + GError *error = NULL; + char **value; if (g_task_return_error_if_cancelled(task)) return; @@ -5403,11 +5473,11 @@ sysctl_async_thread_fn(GTask * task, static void sysctl_set_async_return_idle(gpointer user_data, GCancellable *cancellable) { - gs_unref_object NMPlatform *platform = NULL; - gs_free_error GError *cancelled_error = NULL; - gs_free_error GError * error = NULL; - NMPlatformAsyncCallback callback; - gpointer callback_data; + gs_unref_object NMPlatform *platform = NULL; + gs_free_error GError *cancelled_error = NULL; + gs_free_error GError *error = NULL; + NMPlatformAsyncCallback callback; + gpointer callback_data; nm_utils_user_data_unpack(user_data, &platform, &callback, &callback_data, &error); g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); @@ -5415,20 +5485,20 @@ sysctl_set_async_return_idle(gpointer user_data, GCancellable *cancellable) } static void -sysctl_set_async(NMPlatform * platform, - const char * pathid, +sysctl_set_async(NMPlatform *platform, + const char *pathid, int dirfd, - const char * path, - const char *const * values, + const char *path, + const char *const *values, NMPlatformAsyncCallback callback, gpointer data, - GCancellable * cancellable) + GCancellable *cancellable) { SysctlAsyncInfo *info; - GTask * task; + GTask *task; int dirfd_dup, errsv; gpointer packed; - GError * error = NULL; + GError *error = NULL; g_return_if_fail(platform); g_return_if_fail(path); @@ -5501,7 +5571,7 @@ _nm_logging_clear_platform_logging_cache(void) typedef struct { const char *path; CList lst; - char * value; + char *value; char path_data[]; } SysctlCacheEntry; @@ -5539,7 +5609,7 @@ _log_dbg_sysctl_get_impl(NMPlatform *platform, const char *pathid, const char *c **/ NM_G_MUTEX_LOCKED(&sysctl_clear_cache_lock); NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); - SysctlCacheEntry * entry = NULL; + SysctlCacheEntry *entry = NULL; if (!priv->sysctl_get_prev_values) { c_list_link_tail(&sysctl_clear_cache_lst_head, &priv->sysctl_clear_cache_lst); @@ -5567,7 +5637,7 @@ _log_dbg_sysctl_get_impl(NMPlatform *platform, const char *pathid, const char *c nm_c_list_move_front(&priv->sysctl_list, &entry->lst); } else { - gs_free char * contents_escaped = g_strescape(contents, NULL); + gs_free char *contents_escaped = g_strescape(contents, NULL); SysctlCacheEntry *old; size_t len; @@ -5602,8 +5672,8 @@ static char * sysctl_get(NMPlatform *platform, const char *pathid, int dirfd, const char *path) { nm_auto_pop_netns NMPNetns *netns = NULL; - GError * error = NULL; - gs_free char * contents = NULL; + GError *error = NULL; + gs_free char *contents = NULL; ASSERT_SYSCTL_ARGS(pathid, dirfd, path); @@ -5813,10 +5883,10 @@ static NM_UTILS_LOOKUP_STR_DEFINE( static const char * delayed_action_to_string_full(DelayedActionType action_type, gpointer user_data, - char * buf, + char *buf, gsize buf_size) { - char * buf0 = buf; + char *buf0 = buf; const DelayedActionWaitForNlResponseData *data; nm_strbuf_append_str(&buf, &buf_size, delayed_action_to_string(action_type)); @@ -5831,7 +5901,7 @@ delayed_action_to_string_full(DelayedActionType action_type, data = user_data; if (data) { - gint64 timeout = data->timeout_abs_ns - nm_utils_get_monotonic_timestamp_nsec(); + gint64 timeout = data->timeout_abs_nsec - nm_utils_get_monotonic_timestamp_nsec(); char b[255]; nm_strbuf_append( @@ -5889,11 +5959,11 @@ delayed_action_refresh_all_in_progress(NMPlatform *platform, DelayedActionType a } static void -delayed_action_wait_for_nl_response_complete(NMPlatform * platform, +delayed_action_wait_for_nl_response_complete(NMPlatform *platform, guint idx, WaitForNlResponseResult seq_result) { - NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); DelayedActionWaitForNlResponseData *data; nm_assert(NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)); @@ -5932,17 +6002,17 @@ delayed_action_wait_for_nl_response_complete(NMPlatform * platform, } static void -delayed_action_wait_for_nl_response_complete_check(NMPlatform * platform, +delayed_action_wait_for_nl_response_complete_check(NMPlatform *platform, WaitForNlResponseResult force_result, - guint32 * out_next_seq_number, - gint64 * out_next_timeout_abs_ns, - gint64 * p_now_ns) + guint32 *out_next_seq_number, + gint64 *out_next_timeout_abs_ns, + gint64 *p_now_nsec) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); guint i; guint32 next_seq_number = 0; gint64 next_timeout_abs_ns = 0; - gint64 now_ns = 0; + gint64 now_nsec = 0; for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len;) { const DelayedActionWaitForNlResponseData *data = @@ -5952,10 +6022,10 @@ delayed_action_wait_for_nl_response_complete_check(NMPlatform * platf if (data->seq_result) delayed_action_wait_for_nl_response_complete(platform, i, data->seq_result); - else if (p_now_ns - && ((now_ns ?: (now_ns = nm_utils_get_monotonic_timestamp_nsec())) - >= data->timeout_abs_ns)) { - /* the caller can optionally check for timeout by providing a p_now_ns argument. */ + else if (p_now_nsec + && ((now_nsec ?: (now_nsec = nm_utils_get_monotonic_timestamp_nsec())) + >= data->timeout_abs_nsec)) { + /* the caller can optionally check for timeout by providing a p_now_nsec argument. */ delayed_action_wait_for_nl_response_complete( platform, i, @@ -5963,9 +6033,9 @@ delayed_action_wait_for_nl_response_complete_check(NMPlatform * platf } else if (force_result != WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN) delayed_action_wait_for_nl_response_complete(platform, i, force_result); else { - if (next_seq_number == 0 || next_timeout_abs_ns > data->timeout_abs_ns) { + if (next_seq_number == 0 || next_timeout_abs_ns > data->timeout_abs_nsec) { next_seq_number = data->seq_number; - next_timeout_abs_ns = data->timeout_abs_ns; + next_timeout_abs_ns = data->timeout_abs_nsec; } i++; } @@ -5979,11 +6049,11 @@ delayed_action_wait_for_nl_response_complete_check(NMPlatform * platf NM_SET_OUT(out_next_seq_number, next_seq_number); NM_SET_OUT(out_next_timeout_abs_ns, next_timeout_abs_ns); - NM_SET_OUT(p_now_ns, now_ns); + NM_SET_OUT(p_now_nsec, now_nsec); } static void -delayed_action_wait_for_nl_response_complete_all(NMPlatform * platform, +delayed_action_wait_for_nl_response_complete_all(NMPlatform *platform, WaitForNlResponseResult fallback_result) { delayed_action_wait_for_nl_response_complete_check(platform, fallback_result, NULL, NULL, NULL); @@ -6080,8 +6150,8 @@ delayed_action_handle_one(NMPlatform *platform) priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_ALL; if (_LOGt_ENABLED()) { - FOR_EACH_DELAYED_ACTION(iflags, flags) - _LOGt_delayed_action(iflags, NULL, "handle"); + FOR_EACH_DELAYED_ACTION (iflags, flags) + _LOGt_delayed_action(iflags, NULL, "handle"); } delayed_action_handle_REFRESH_ALL(platform, flags); @@ -6177,22 +6247,22 @@ delayed_action_schedule(NMPlatform *platform, DelayedActionType action_type, gpo priv->delayed_action.flags |= action_type; if (_LOGt_ENABLED()) { - FOR_EACH_DELAYED_ACTION(iflags, action_type) - _LOGt_delayed_action(iflags, user_data, "schedule"); + FOR_EACH_DELAYED_ACTION (iflags, action_type) + _LOGt_delayed_action(iflags, user_data, "schedule"); } } static void -delayed_action_schedule_WAIT_FOR_NL_RESPONSE(NMPlatform * platform, +delayed_action_schedule_WAIT_FOR_NL_RESPONSE(NMPlatform *platform, guint32 seq_number, - WaitForNlResponseResult * out_seq_result, - char ** out_errmsg, + WaitForNlResponseResult *out_seq_result, + char **out_errmsg, DelayedActionWaitForNlResponseType response_type, gpointer response_out_data) { DelayedActionWaitForNlResponseData data = { .seq_number = seq_number, - .timeout_abs_ns = + .timeout_abs_nsec = nm_utils_get_monotonic_timestamp_nsec() + (200 * (NM_UTILS_NSEC_PER_SEC / 1000)), .out_seq_result = out_seq_result, .out_errmsg = out_errmsg, @@ -6211,7 +6281,7 @@ cache_prune_one_type(NMPlatform *platform, const NMPLookup *lookup) NMDedupMultiIter iter; const NMPObject *obj; NMPCacheOpsType cache_op; - NMPCache * cache = nm_platform_get_cache(platform); + NMPCache *cache = nm_platform_get_cache(platform); nm_dedup_multi_iter_init(&iter, nmp_cache_lookup(cache, lookup)); while (nm_dedup_multi_iter_next(&iter)) { @@ -6260,7 +6330,7 @@ cache_prune_all(NMPlatform *platform) } static void -cache_on_change(NMPlatform * platform, +cache_on_change(NMPlatform *platform, NMPCacheOpsType cache_op, const NMPObject *obj_old, const NMPObject *obj_new) @@ -6268,7 +6338,7 @@ cache_on_change(NMPlatform * platform, const NMPClass *klass; char str_buf[sizeof(_nm_utils_to_string_buffer)]; char str_buf2[sizeof(_nm_utils_to_string_buffer)]; - NMPCache * cache = nm_platform_get_cache(platform); + NMPCache *cache = nm_platform_get_cache(platform); ASSERT_nmp_cache_ops(cache, cache_op, obj_old, obj_new); nm_assert(cache_op != NMP_CACHE_OPS_UNCHANGED); @@ -6531,10 +6601,10 @@ _nlh_seq_next_get(NMLinuxPlatformPrivate *priv) * Returns: 0 on success or a negative errno. */ static int -_nl_send_nlmsghdr(NMPlatform * platform, - struct nlmsghdr * nlhdr, - WaitForNlResponseResult * out_seq_result, - char ** out_errmsg, +_nl_send_nlmsghdr(NMPlatform *platform, + struct nlmsghdr *nlhdr, + WaitForNlResponseResult *out_seq_result, + char **out_errmsg, DelayedActionWaitForNlResponseType response_type, gpointer response_out_data) { @@ -6598,15 +6668,15 @@ again: * Returns: 0 on success, or a negative libnl3 error code (beware, it's not an errno). */ static int -_nl_send_nlmsg(NMPlatform * platform, - struct nl_msg * nlmsg, - WaitForNlResponseResult * out_seq_result, - char ** out_errmsg, +_nl_send_nlmsg(NMPlatform *platform, + struct nl_msg *nlmsg, + WaitForNlResponseResult *out_seq_result, + char **out_errmsg, DelayedActionWaitForNlResponseType response_type, gpointer response_out_data) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); - struct nlmsghdr * nlhdr; + struct nlmsghdr *nlhdr; guint32 seq; int nle; @@ -6632,7 +6702,7 @@ _nl_send_nlmsg(NMPlatform * platform, static void do_request_link_no_delayed_actions(NMPlatform *platform, int ifindex, const char *name) { - NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); nm_auto_nlmsg struct nl_msg *nlmsg = NULL; int nle; @@ -6680,7 +6750,7 @@ static struct nl_msg * _nl_msg_new_dump(NMPObjectType obj_type, int preferred_addr_family) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - const NMPClass * klass; + const NMPClass *klass; klass = nmp_class_from_type(obj_type); @@ -6753,8 +6823,7 @@ do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action action_type_prune &= ~DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL; } - FOR_EACH_DELAYED_ACTION(iflags, action_type_prune) - { + FOR_EACH_DELAYED_ACTION (iflags, action_type_prune) { RefreshAllType refresh_all_type = delayed_action_type_to_refresh_all_type(iflags); NMPLookup lookup; @@ -6763,12 +6832,11 @@ do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action nmp_cache_dirty_set_all_main(nm_platform_get_cache(platform), &lookup); } - FOR_EACH_DELAYED_ACTION(iflags, action_type) - { + FOR_EACH_DELAYED_ACTION (iflags, action_type) { RefreshAllType refresh_all_type = delayed_action_type_to_refresh_all_type(iflags); const RefreshAllInfo *refresh_all_info = refresh_all_type_get_info(refresh_all_type); nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - int * out_refresh_all_in_progress; + int *out_refresh_all_in_progress; out_refresh_all_in_progress = &priv->delayed_action.refresh_all_in_progress[refresh_all_type]; @@ -6826,7 +6894,7 @@ do_request_one_type_by_needle_object(NMPlatform *platform, const NMPObject *obj_ static void event_seq_check_refresh_all(NMPlatform *platform, guint32 seq_number) { - NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); DelayedActionWaitForNlResponseData *data; guint i; @@ -6855,12 +6923,12 @@ event_seq_check_refresh_all(NMPlatform *platform, guint32 seq_number) } static void -event_seq_check(NMPlatform * platform, +event_seq_check(NMPlatform *platform, guint32 seq_number, WaitForNlResponseResult seq_result, - const char * msg) + const char *msg) { - NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); DelayedActionWaitForNlResponseData *data; guint i; @@ -6901,14 +6969,14 @@ event_seq_check(NMPlatform * platform, static void event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events) { - NMLinuxPlatformPrivate *priv; + NMLinuxPlatformPrivate *priv; nm_auto_nmpobj NMPObject *obj = NULL; NMPCacheOpsType cache_op; - struct nlmsghdr * msghdr; + struct nlmsghdr *msghdr; char buf_nlmsghdr[400]; gboolean is_del = FALSE; gboolean is_dump = FALSE; - NMPCache * cache = nm_platform_get_cache(platform); + NMPCache *cache = nm_platform_get_cache(platform); msghdr = nlmsg_hdr(msg); @@ -7010,6 +7078,17 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events } } + if (ip_route_ignored_protocol(NMP_OBJECT_CAST_IP_ROUTE(obj))) { + /* We ignore certain rtm_protocol, because NetworkManager would only ever + * configure certain protocols. Other routes were not added by NetworkManager + * and we don't need to track them in the platform cache. + * + * This is to help with the performance overhead of a huge number of + * routes, for example with the bird BGP software, that adds routes + * with RTPROT_BIRD protocol. */ + return; + } + cache_op = nmp_cache_update_netlink_route(cache, obj, is_dump, @@ -7085,18 +7164,18 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events /*****************************************************************************/ static int -do_add_link_with_lookup(NMPlatform * platform, +do_add_link_with_lookup(NMPlatform *platform, NMLinkType link_type, - const char * name, - struct nl_msg * nlmsg, + const char *name, + struct nl_msg *nlmsg, const NMPlatformLink **out_link) { - const NMPObject * obj = NULL; + const NMPObject *obj = NULL; WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; int nle; char s_buf[256]; - NMPCache * cache = nm_platform_get_cache(platform); + NMPCache *cache = nm_platform_get_cache(platform); event_handler_read_netlink(platform, FALSE); @@ -7135,13 +7214,13 @@ do_add_link_with_lookup(NMPlatform * platform, } static int -do_add_addrroute(NMPlatform * platform, +do_add_addrroute(NMPlatform *platform, const NMPObject *obj_id, - struct nl_msg * nlmsg, + struct nl_msg *nlmsg, gboolean suppress_netlink_failure) { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; int nle; char s_buf[256]; @@ -7200,11 +7279,11 @@ static gboolean do_delete_object(NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *nlmsg) { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; int nle; char s_buf[256]; gboolean success; - const char * log_detail = ""; + const char *log_detail = ""; event_handler_read_netlink(platform, FALSE); @@ -7270,23 +7349,23 @@ do_delete_object(NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *n } static int -do_change_link(NMPlatform * platform, +do_change_link(NMPlatform *platform, ChangeLinkType change_link_type, int ifindex, - struct nl_msg * nlmsg, + struct nl_msg *nlmsg, const ChangeLinkData *data) { nm_auto_pop_netns NMPNetns *netns = NULL; int nle; WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; char s_buf[256]; int result = 0; NMLogLevel log_level = LOGL_DEBUG; - const char * log_result = "failure"; - const char * log_detail = ""; - gs_free char * log_detail_free = NULL; - const NMPObject * obj_cache; + const char *log_result = "failure"; + const char *log_detail = ""; + gs_free char *log_detail_free = NULL; + const NMPObject *obj_cache; if (!nm_platform_netns_push(platform, &netns)) { log_level = LOGL_ERR; @@ -7368,11 +7447,11 @@ out: } static int -link_add(NMPlatform * platform, +link_add(NMPlatform *platform, NMLinkType type, - const char * name, + const char *name, int parent, - const void * address, + const void *address, size_t address_len, guint32 mtu, gconstpointer extra_data, @@ -7418,7 +7497,7 @@ link_delete(NMPlatform *platform, int ifindex) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; NMPObject obj_id; - const NMPObject * obj; + const NMPObject *obj; obj = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex); if (!obj || !obj->_link.netlink.is_in_netlink) @@ -7527,7 +7606,7 @@ static gboolean link_supports_vlans(NMPlatform *platform, int ifindex) { nm_auto_pop_netns NMPNetns *netns = NULL; - const NMPObject * obj; + const NMPObject *obj; obj = nm_platform_link_get_obj(platform, ifindex, TRUE); @@ -7569,10 +7648,10 @@ link_set_address(NMPlatform *platform, int ifindex, gconstpointer address, size_ { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; const ChangeLinkData d = { - .set_address = + .set_address = { - .address = address, - .length = length, + .address = address, + .length = length, }, }; @@ -7643,11 +7722,11 @@ nla_put_failure: static void sriov_idle_cb(gpointer user_data, GCancellable *cancellable) { - gs_unref_object NMPlatform *platform = NULL; - gs_free_error GError *cancelled_error = NULL; - gs_free_error GError * error = NULL; - NMPlatformAsyncCallback callback; - gpointer callback_data; + gs_unref_object NMPlatform *platform = NULL; + gs_free_error GError *cancelled_error = NULL; + gs_free_error GError *error = NULL; + NMPlatformAsyncCallback callback; + gpointer callback_data; g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); nm_utils_user_data_unpack(user_data, &platform, &error, &callback, &callback_data); @@ -7655,24 +7734,24 @@ sriov_idle_cb(gpointer user_data, GCancellable *cancellable) } static void -link_set_sriov_params_async(NMPlatform * platform, +link_set_sriov_params_async(NMPlatform *platform, int ifindex, guint num_vfs, NMOptionBool autoprobe, NMPlatformAsyncCallback callback, gpointer data, - GCancellable * cancellable) + GCancellable *cancellable) { nm_auto_pop_netns NMPNetns *netns = NULL; - gs_free_error GError *error = NULL; - nm_auto_close int dirfd = -1; - int current_autoprobe; - guint i, total; - gint64 current_num; - char ifname[IFNAMSIZ]; - gpointer packed; - const char * values[3]; - char buf[64]; + gs_free_error GError *error = NULL; + nm_auto_close int dirfd = -1; + int current_autoprobe; + guint i, total; + gint64 current_num; + char ifname[IFNAMSIZ]; + gpointer packed; + const char *values[3]; + char buf[64]; g_return_if_fail(callback || !data); g_return_if_fail(cancellable); @@ -7781,7 +7860,7 @@ static gboolean link_set_sriov_vfs(NMPlatform *platform, int ifindex, const NMPlatformVF *const *vfs) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr * list, *info, *vlan_list; + struct nlattr *list, *info, *vlan_list; guint i; nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); @@ -7868,13 +7947,13 @@ nla_put_failure: } static gboolean -link_set_bridge_vlans(NMPlatform * platform, +link_set_bridge_vlans(NMPlatform *platform, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr * list; + struct nlattr *list; struct bridge_vlan_info vinfo = {}; guint i; @@ -7959,13 +8038,13 @@ link_get_dev_id(NMPlatform *platform, int ifindex) } static gboolean -link_tun_add(NMPlatform * platform, - const char * name, +link_tun_add(NMPlatform *platform, + const char *name, const NMPlatformLnkTun *props, - const NMPlatformLink ** out_link, - int * out_fd) + const NMPlatformLink **out_link, + int *out_fd) { - const NMPObject * obj; + const NMPObject *obj; struct ifreq ifr = {}; nm_auto_close int fd = -1; @@ -8023,8 +8102,8 @@ _vlan_change_vlan_qos_mapping_create(gboolean is_ingress_map, guint current_n_map, const NMVlanQosMapping *set_map, guint set_n_map, - NMVlanQosMapping ** out_map, - guint * out_n_map) + NMVlanQosMapping **out_map, + guint *out_n_map) { NMVlanQosMapping *map; guint i, j, len; @@ -8087,7 +8166,7 @@ _vlan_change_vlan_qos_mapping_create(gboolean is_ingress_map, } static gboolean -link_vlan_change(NMPlatform * platform, +link_vlan_change(NMPlatform *platform, int ifindex, _NMVlanFlags flags_mask, _NMVlanFlags flags_set, @@ -8098,13 +8177,13 @@ link_vlan_change(NMPlatform * platform, const NMVlanQosMapping *egress_map, gsize n_egress_map) { - const NMPObject * obj_cache; + const NMPObject *obj_cache; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - const NMPObjectLnkVlan * lnk; + const NMPObjectLnkVlan *lnk; guint new_n_ingress_map = 0; guint new_n_egress_map = 0; - gs_free NMVlanQosMapping *new_ingress_map = NULL; - gs_free NMVlanQosMapping *new_egress_map = NULL; + gs_free NMVlanQosMapping *new_ingress_map = NULL; + gs_free NMVlanQosMapping *new_egress_map = NULL; obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex); if (!obj_cache || !obj_cache->_link.netlink.is_in_netlink) { @@ -8175,7 +8254,7 @@ link_release(NMPlatform *platform, int master, int slave) /*****************************************************************************/ static gboolean -_infiniband_partition_action(NMPlatform * platform, +_infiniband_partition_action(NMPlatform *platform, InfinibandAction action, int parent, int p_key, @@ -8183,7 +8262,7 @@ _infiniband_partition_action(NMPlatform * platform, { nm_auto_close int dirfd = -1; char ifname_parent[IFNAMSIZ]; - const NMPObject * obj; + const NMPObject *obj; char id[20]; char name[IFNAMSIZ]; gboolean success; @@ -8234,7 +8313,7 @@ _infiniband_partition_action(NMPlatform * platform, } static gboolean -infiniband_partition_add(NMPlatform * platform, +infiniband_partition_add(NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) @@ -8274,7 +8353,7 @@ get_ext_data(NMPlatform *platform, int ifindex) #define WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, retval) \ nm_auto_pop_netns NMPNetns *netns = NULL; \ - NMWifiUtils * wifi_data; \ + NMWifiUtils *wifi_data; \ if (!nm_platform_netns_push(platform, &netns)) \ return retval; \ wifi_data = NM_WIFI_UTILS(get_ext_data(platform, ifindex)); \ @@ -8298,11 +8377,11 @@ wifi_get_frequency(NMPlatform *platform, int ifindex) } static gboolean -wifi_get_station(NMPlatform * platform, +wifi_get_station(NMPlatform *platform, int ifindex, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate) + int *out_quality, + guint32 *out_rate) { WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); return nm_wifi_utils_get_station(wifi_data, out_bssid, out_quality, out_rate); @@ -8365,7 +8444,7 @@ link_can_assume(NMPlatform *platform, int ifindex) NMPLookup lookup; const NMPObject *link, *o; NMDedupMultiIter iter; - NMPCache * cache = nm_platform_get_cache(platform); + NMPCache *cache = nm_platform_get_cache(platform); if (ifindex <= 0) return FALSE; @@ -8488,9 +8567,9 @@ link_get_wake_on_lan(NMPlatform *platform, int ifindex) static gboolean link_get_driver_info(NMPlatform *platform, int ifindex, - char ** out_driver_name, - char ** out_driver_version, - char ** out_fw_version) + char **out_driver_name, + char **out_driver_version, + char **out_fw_version) { nm_auto_pop_netns NMPNetns *netns = NULL; NMPUtilsEthtoolDriverInfo driver_info; @@ -8543,7 +8622,7 @@ ip4_address_add(NMPlatform *platform, } static gboolean -ip6_address_add(NMPlatform * platform, +ip6_address_add(NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen, @@ -8632,7 +8711,7 @@ ip6_address_delete(NMPlatform *platform, int ifindex, struct in6_addr addr, guin /*****************************************************************************/ static int -ip_route_add(NMPlatform * platform, +ip_route_add(NMPlatform *platform, NMPNlmFlags flags, int addr_family, const NMPlatformIPRoute *route) @@ -8659,7 +8738,7 @@ static gboolean object_delete(NMPlatform *platform, const NMPObject *obj) { nm_auto_nmpobj const NMPObject *obj_keep_alive = NULL; - nm_auto_nlmsg struct nl_msg * nlmsg = NULL; + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; if (!NMP_OBJECT_IS_STACKINIT(obj)) obj_keep_alive = nmp_object_ref(obj); @@ -8690,17 +8769,17 @@ object_delete(NMPlatform *platform, const NMPObject *obj) /*****************************************************************************/ static int -ip_route_get(NMPlatform * platform, +ip_route_get(NMPlatform *platform, int addr_family, gconstpointer address, int oif_ifindex, - NMPObject ** out_route) + NMPObject **out_route) { - const gboolean is_v4 = (addr_family == AF_INET); - const int addr_len = is_v4 ? 4 : 16; - int try_count = 0; - WaitForNlResponseResult seq_result; - int nle; + const gboolean IS_IPv4 = NM_IS_IPv4(addr_family); + const int addr_len = IS_IPv4 ? 4 : 16; + int try_count = 0; + WaitForNlResponseResult seq_result; + int nle; nm_auto_nmpobj NMPObject *route = NULL; nm_assert(NM_IS_LINUX_PLATFORM(platform)); @@ -8718,7 +8797,7 @@ ip_route_get(NMPlatform * platform, .n.nlmsg_type = RTM_GETROUTE, .r.rtm_family = addr_family, .r.rtm_tos = 0, - .r.rtm_dst_len = is_v4 ? 32 : 128, + .r.rtm_dst_len = IS_IPv4 ? 32 : 128, .r.rtm_flags = 0x1000 /* RTM_F_LOOKUP_TABLE */, }; @@ -8778,7 +8857,7 @@ routing_rule_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformRoutin { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; nm_auto_nlmsg struct nl_msg *msg = NULL; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; char s_buf[256]; int nle; @@ -8818,7 +8897,7 @@ static int qdisc_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; int nle; char s_buf[256]; nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -8860,14 +8939,14 @@ static int tc_delete(NMPlatform *platform, int nlmsgtype, int ifindex, guint32 parent, gboolean log_error) { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; int nle; char s_buf[256]; - const char * log_tag; + const char *log_tag; nm_auto_nlmsg struct nl_msg *msg = NULL; const struct tcmsg tcm = { - .tcm_ifindex = ifindex, - .tcm_parent = parent, + .tcm_ifindex = ifindex, + .tcm_parent = parent, }; switch (nlmsgtype) { @@ -8934,7 +9013,7 @@ static int tfilter_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformTfilter *tfilter) { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; - gs_free char * errmsg = NULL; + gs_free char *errmsg = NULL; int nle; char s_buf[256]; nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -8992,39 +9071,44 @@ event_handler(int fd, GIOCondition io_condition, gpointer user_data) static int event_handler_recvmsgs(NMPlatform *platform, gboolean handle_events) { - NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); - struct nl_sock * sk = priv->nlh; - int n; - int err = 0; - gboolean multipart = 0; - gboolean interrupted = FALSE; - struct nlmsghdr * hdr; - WaitForNlResponseResult seq_result; - struct sockaddr_nl nla = {0}; - struct ucred creds; - gboolean creds_has; - nm_auto_free unsigned char *buf = NULL; + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + struct nl_sock *sk = priv->nlh; + int n; + int err = 0; + gboolean multipart = 0; + gboolean interrupted = FALSE; + struct nlmsghdr *hdr; + WaitForNlResponseResult seq_result; + struct sockaddr_nl nla; + struct ucred creds; + gboolean creds_has; + unsigned char *buf; continue_reading: - nm_clear_pointer(&buf, free); - n = nl_recv(sk, &nla, &buf, &creds, &creds_has); + buf = NULL; + + n = nl_recv(sk, + priv->netlink_recv_buf.buf, + priv->netlink_recv_buf.len, + &nla, + &buf, + &creds, + &creds_has); + + nm_assert((n <= 0 && !buf) + || (n > 0 && n <= priv->netlink_recv_buf.len && buf == priv->netlink_recv_buf.buf)); if (n <= 0) { if (n == -NME_NL_MSG_TRUNC) { - int buf_size; - /* the message receive buffer was too small. We lost one message, which * is unfortunate. Try to double the buffer size for the next time. */ - buf_size = nl_socket_get_msg_buf_size(sk); - if (buf_size < 512 * 1024) { - buf_size *= 2; - _LOGT("netlink: recvmsg: increase message buffer size for recvmsg() to %d bytes", - buf_size); - if (nl_socket_set_msg_buf_size(sk, buf_size) < 0) - nm_assert_not_reached(); - if (!handle_events) - goto continue_reading; - } + priv->netlink_recv_buf.len *= 2; + priv->netlink_recv_buf.buf = + g_realloc(priv->netlink_recv_buf.buf, priv->netlink_recv_buf.len); + _LOGT("netlink: recvmsg: increase message buffer size for recvmsg() to %zu bytes", + priv->netlink_recv_buf.len); + if (!handle_events) + goto continue_reading; } return n; @@ -9037,7 +9121,7 @@ continue_reading: gboolean process_valid_msg = FALSE; guint32 seq_number; char buf_nlmsghdr[400]; - const char * extack_msg = NULL; + const char *extack_msg = NULL; msg = nlmsg_alloc_convert(hdr); @@ -9195,15 +9279,15 @@ static gboolean event_handler_read_netlink(NMPlatform *platform, gboolean wait_for_acks) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); int r; struct pollfd pfd; gboolean any = FALSE; int timeout_msec; struct { guint32 seq_number; - gint64 timeout_abs_ns; - gint64 now_ns; + gint64 timeout_abs_nsec; + gint64 now_nsec; } next; if (!nm_platform_netns_push(platform, &netns)) { @@ -9275,25 +9359,33 @@ after_read: delayed_action_wait_for_nl_response_complete_check(platform, WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN, &next.seq_number, - &next.timeout_abs_ns, - &next.now_ns); + &next.timeout_abs_nsec, + &next.now_nsec); if (!wait_for_acks || !NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) return any; nm_assert(next.seq_number); - nm_assert(next.now_ns > 0); - nm_assert(next.timeout_abs_ns > next.now_ns); + nm_assert(next.now_nsec > 0); + nm_assert(next.timeout_abs_nsec > next.now_nsec); + nm_assert(next.timeout_abs_nsec - next.now_nsec <= 200 * (NM_UTILS_NSEC_PER_SEC / 1000)); - _LOGT("netlink: read: wait for ACK for sequence number %u...", next.seq_number); + timeout_msec = + NM_CLAMP((next.timeout_abs_nsec - next.now_nsec) / (NM_UTILS_NSEC_PER_SEC / 1000), + 1, + 1000); - timeout_msec = (next.timeout_abs_ns - next.now_ns) / (NM_UTILS_NSEC_PER_SEC / 1000); + _LOGT("netlink: read: wait for ACK for sequence number %u... (%d msec)", + next.seq_number, + timeout_msec); memset(&pfd, 0, sizeof(pfd)); pfd.fd = nl_socket_get_fd(priv->nlh); pfd.events = POLLIN; - r = poll(&pfd, 1, MAX(1, timeout_msec)); + r = poll(&pfd, 1, timeout_msec); + + _LOGT("netlink: read: poll done (r=%d)", r); if (r == 0) { /* timeout and there is nothing to read. */ @@ -9412,11 +9504,11 @@ static void handle_udev_event(NMUdevClient *udev_client, struct udev_device *udevice, gpointer user_data) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMPlatform * platform = NM_PLATFORM(user_data); - const char * subsys; - const char * ifindex; + NMPlatform *platform = NM_PLATFORM(user_data); + const char *subsys; + const char *ifindex; guint64 seqnum; - const char * action; + const char *action; action = udev_device_get_action(udevice); g_return_if_fail(action); @@ -9449,6 +9541,9 @@ nm_linux_platform_init(NMLinuxPlatform *self) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(self); + priv->netlink_recv_buf.len = 32 * 1024; + priv->netlink_recv_buf.buf = g_malloc(priv->netlink_recv_buf.len); + c_list_init(&priv->sysctl_clear_cache_lst); c_list_init(&priv->sysctl_list); @@ -9461,7 +9556,7 @@ nm_linux_platform_init(NMLinuxPlatform *self) static void constructed(GObject *_object) { - NMPlatform * platform = NM_PLATFORM(_object); + NMPlatform *platform = NM_PLATFORM(_object); NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); int nle; int fd; @@ -9517,10 +9612,10 @@ constructed(GObject *_object) _LOGD("could not enable extended acks on netlink socket"); /* explicitly set the msg buffer size and disable MSG_PEEK. - * If we later encounter NME_NL_MSG_TRUNC, we will adjust the buffer size. */ + * We use our own receive buffer priv->netlink_recv_buf. + * If we encounter NME_NL_MSG_TRUNC, we will increase the buffer + * and resync (as we would have lost the message without NL_MSG_PEEK). */ nl_socket_disable_msg_peek(priv->nlh); - nle = nl_socket_set_msg_buf_size(priv->nlh, 32 * 1024); - g_assert(!nle); nle = nl_socket_add_memberships(priv->nlh, RTNLGRP_IPV4_IFADDR, @@ -9571,7 +9666,7 @@ constructed(GObject *_object) /* Set up udev monitoring */ if (priv->udev_client) { - struct udev_enumerate * enumerator; + struct udev_enumerate *enumerator; struct udev_list_entry *devices, *l; /* And read initial device list */ @@ -9643,7 +9738,7 @@ nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support, gboolean ca static void dispose(GObject *object) { - NMPlatform * platform = NM_PLATFORM(object); + NMPlatform *platform = NM_PLATFORM(object); NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); _LOGD("dispose"); @@ -9688,12 +9783,14 @@ finalize(GObject *object) priv->udev_client = nm_udev_client_destroy(priv->udev_client); G_OBJECT_CLASS(nm_linux_platform_parent_class)->finalize(object); + + g_free(priv->netlink_recv_buf.buf); } static void nm_linux_platform_class_init(NMLinuxPlatformClass *klass) { - GObjectClass * object_class = G_OBJECT_CLASS(klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); NMPlatformClass *platform_class = NM_PLATFORM_CLASS(klass); object_class->constructed = constructed; diff --git a/src/libnm-platform/nm-netlink.c b/src/libnm-platform/nm-netlink.c index 56cde50c..697ae591 100644 --- a/src/libnm-platform/nm-netlink.c +++ b/src/libnm-platform/nm-netlink.c @@ -32,7 +32,7 @@ struct nl_msg { struct sockaddr_nl nm_src; struct sockaddr_nl nm_dst; struct ucred nm_creds; - struct nlmsghdr * nm_nlh; + struct nlmsghdr *nm_nlh; size_t nm_size; bool nm_creds_has : 1; }; @@ -245,7 +245,7 @@ nlmsg_hdr(struct nl_msg *n) void * nlmsg_reserve(struct nl_msg *n, size_t len, int pad) { - char * buf = (char *) n->nm_nlh; + char *buf = (char *) n->nm_nlh; size_t nlmsg_len = n->nm_nlh->nlmsg_len; size_t tlen; @@ -386,9 +386,9 @@ nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad) /*****************************************************************************/ int -nlmsg_parse(struct nlmsghdr * nlh, +nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, - struct nlattr * tb[], + struct nlattr *tb[], int maxtype, const struct nla_policy *policy) { @@ -639,9 +639,9 @@ validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *pol } int -nla_parse(struct nlattr * tb[], +nla_parse(struct nlattr *tb[], int maxtype, - struct nlattr * head, + struct nlattr *head, int len, const struct nla_policy *policy) { @@ -718,7 +718,7 @@ genlmsg_put(struct nl_msg *msg, uint8_t cmd, uint8_t version) { - struct nlmsghdr * nlh; + struct nlmsghdr *nlh; struct genlmsghdr hdr = { .cmd = cmd, .version = version, @@ -794,9 +794,9 @@ genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen) } int -genlmsg_parse(struct nlmsghdr * nlh, +genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, - struct nlattr * tb[], + struct nlattr *tb[], int maxtype, const struct nla_policy *policy) { @@ -825,9 +825,9 @@ _genl_parse_getfamily(struct nl_msg *msg, void *arg) [CTRL_ATTR_OPS] = {.type = NLA_NESTED}, [CTRL_ATTR_MCAST_GROUPS] = {.type = NLA_NESTED}, }; - struct nlattr * tb[G_N_ELEMENTS(ctrl_policy)]; + struct nlattr *tb[G_N_ELEMENTS(ctrl_policy)]; struct nlmsghdr *nlh = nlmsg_hdr(msg); - gint32 * response_data = arg; + gint32 *response_data = arg; if (genlmsg_parse_arr(nlh, 0, tb, ctrl_policy) < 0) return NL_SKIP; @@ -845,8 +845,8 @@ genl_ctrl_resolve(struct nl_sock *sk, const char *name) int nmerr; gint32 response_data = -1; const struct nl_cb cb = { - .valid_cb = _genl_parse_getfamily, - .valid_arg = &response_data, + .valid_cb = _genl_parse_getfamily, + .valid_arg = &response_data, }; msg = nlmsg_alloc(); @@ -1170,13 +1170,13 @@ nl_recvmsgs(struct nl_sock *sk, const struct nl_cb *cb) { int n, nmerr = 0, multipart = 0, interrupted = 0, nrecv = 0; gs_free unsigned char *buf = NULL; - struct nlmsghdr * hdr; - struct sockaddr_nl nla = {0}; + struct nlmsghdr *hdr; + struct sockaddr_nl nla; struct ucred creds; gboolean creds_has; continue_reading: - n = nl_recv(sk, &nla, &buf, &creds, &creds_has); + n = nl_recv(sk, NULL, 0, &nla, &buf, &creds, &creds_has); if (n <= 0) return n; @@ -1327,12 +1327,12 @@ int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen) { struct sockaddr_nl *dst; - struct ucred * creds; + struct ucred *creds; struct msghdr hdr = { - .msg_name = (void *) &sk->s_peer, - .msg_namelen = sizeof(struct sockaddr_nl), - .msg_iov = iov, - .msg_iovlen = iovlen, + .msg_name = (void *) &sk->s_peer, + .msg_namelen = sizeof(struct sockaddr_nl), + .msg_iov = iov, + .msg_iovlen = iovlen, }; char buf[CMSG_SPACE(sizeof(struct ucred))]; @@ -1401,12 +1401,41 @@ nl_send_auto(struct nl_sock *sk, struct nl_msg *msg) return nl_send(sk, msg); } +/** + * nl_recv(): + * @sk: the netlink socket + * @buf0: NULL or a receive buffer of length @buf0_len + * @buf0_len: the length of the optional receive buffer. + * @nla: (out): the source address on success. + * @buf: (out): pointer to the result buffer on success. This is + * either @buf0 or an allocated buffer that gets returned. + * @out_creds: (out) (allow-none): optional out buffer for the credentials + * on success. + * @out_creds_has: (out) (allow-none): result indicating whether + * @out_creds was filled. + * + * If @buf0_len is zero, the function will g_malloc() a new receive buffer of size + * nl_socket_get_msg_buf_size(). If @buf0_len is larger than zero, then @buf0 + * is used as receive buffer. That is also the buffer returned by @buf. + * + * If NL_MSG_PEEK is not enabled and the receive buffer is too small, then + * the message was lost and -NME_NL_MSG_TRUNC gets returned. + * If NL_MSG_PEEK is enabled, then we first peek. If the buffer is too small, + * we g_malloc() a new buffer. In any case, we proceed to receive the buffer. + * NL_MSG_PEEK is great because it means no messages are lost. But it's bad, + * because we always need two syscalls on every receive. + * + * Returns: a negative error code or the length of the received message in + * @buf. + */ int -nl_recv(struct nl_sock * sk, +nl_recv(struct nl_sock *sk, + unsigned char *buf0, + size_t buf0_len, struct sockaddr_nl *nla, - unsigned char ** buf, - struct ucred * out_creds, - gboolean * out_creds_has) + unsigned char **buf, + struct ucred *out_creds, + gboolean *out_creds_has) { /* We really expect msg_contol_buf to be large enough and MSG_CTRUNC not * happening. We nm_assert() against that. However, in release builds @@ -1443,8 +1472,13 @@ nl_recv(struct nl_sock * sk, || (!(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0)) flags |= MSG_PEEK | MSG_TRUNC; - iov.iov_len = sk->s_bufsize ?: (((size_t) nm_utils_getpagesize()) * 4u); - iov.iov_base = g_malloc(iov.iov_len); + if (buf0_len > 0) { + iov.iov_len = buf0_len; + iov.iov_base = buf0; + } else { + iov.iov_len = sk->s_bufsize ?: (((size_t) nm_utils_getpagesize()) * 4u); + iov.iov_base = g_malloc(iov.iov_len); + } if (out_creds && (sk->s_flags & NL_SOCK_PASSCRED)) { msg.msg_controllen = sizeof(msg_contol_buf); @@ -1482,7 +1516,7 @@ retry: /* Provided buffer is not long enough, enlarge it * to size of n (which should be total length of the message) * and try again. */ - iov.iov_base = g_realloc(iov.iov_base, n); + iov.iov_base = g_realloc(iov.iov_base != buf0 ? iov.iov_base : NULL, n); iov.iov_len = n; flags = 0; goto retry; @@ -1517,7 +1551,8 @@ retry: abort: if (retval <= 0) { - g_free(iov.iov_base); + if (iov.iov_base != buf0) + g_free(iov.iov_base); return retval; } diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h index 00d817cd..bb1e41ee 100644 --- a/src/libnm-platform/nm-netlink.h +++ b/src/libnm-platform/nm-netlink.h @@ -328,9 +328,9 @@ void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr); struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype); int nla_nest_end(struct nl_msg *msg, struct nlattr *start); -int nla_parse(struct nlattr * tb[], +int nla_parse(struct nlattr *tb[], int maxtype, - struct nlattr * head, + struct nlattr *head, int len, const struct nla_policy *policy); @@ -342,9 +342,9 @@ int nla_parse(struct nlattr * tb[], }) static inline int -nla_parse_nested(struct nlattr * tb[], +nla_parse_nested(struct nlattr *tb[], int maxtype, - struct nlattr * nla, + struct nlattr *nla, const struct nla_policy *policy) { return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); @@ -468,9 +468,9 @@ nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype) return nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), attrtype); } -int nlmsg_parse(struct nlmsghdr * nlh, +int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, - struct nlattr * tb[], + struct nlattr *tb[], int maxtype, const struct nla_policy *policy); @@ -517,11 +517,13 @@ int nl_socket_add_memberships(struct nl_sock *sk, int group, ...); int nl_connect(struct nl_sock *sk, int protocol); -int nl_recv(struct nl_sock * sk, +int nl_recv(struct nl_sock *sk, + unsigned char *buf0, + size_t buf0_len, struct sockaddr_nl *nla, - unsigned char ** buf, - struct ucred * out_creds, - gboolean * out_creds_has); + unsigned char **buf, + struct ucred *out_creds, + gboolean *out_creds_has); int nl_send(struct nl_sock *sk, struct nl_msg *msg); @@ -544,16 +546,16 @@ typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, struct nlmsgerr *nle struct nl_cb { nl_recvmsg_msg_cb_t valid_cb; - void * valid_arg; + void *valid_arg; nl_recvmsg_msg_cb_t finish_cb; - void * finish_arg; + void *finish_arg; nl_recvmsg_msg_cb_t ack_cb; - void * ack_arg; + void *ack_arg; nl_recvmsg_err_cb_t err_cb; - void * err_arg; + void *err_arg; }; int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr); @@ -570,7 +572,7 @@ int nl_socket_set_ext_ack(struct nl_sock *sk, gboolean enable); /*****************************************************************************/ -void * genlmsg_put(struct nl_msg *msg, +void *genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, @@ -578,18 +580,18 @@ void * genlmsg_put(struct nl_msg *msg, int flags, uint8_t cmd, uint8_t version); -void * genlmsg_data(const struct genlmsghdr *gnlh); -void * genlmsg_user_hdr(const struct genlmsghdr *gnlh); +void *genlmsg_data(const struct genlmsghdr *gnlh); +void *genlmsg_user_hdr(const struct genlmsghdr *gnlh); struct genlmsghdr *genlmsg_hdr(struct nlmsghdr *nlh); -void * genlmsg_user_data(const struct genlmsghdr *gnlh, const int hdrlen); -struct nlattr * genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen); +void *genlmsg_user_data(const struct genlmsghdr *gnlh, const int hdrlen); +struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen); int genlmsg_len(const struct genlmsghdr *gnlh); int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen); int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen); -int genlmsg_parse(struct nlmsghdr * nlh, +int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, - struct nlattr * tb[], + struct nlattr *tb[], int maxtype, const struct nla_policy *policy); diff --git a/src/libnm-platform/nm-platform-private.h b/src/libnm-platform/nm-platform-private.h index cf805689..7537bb0b 100644 --- a/src/libnm-platform/nm-platform-private.h +++ b/src/libnm-platform/nm-platform-private.h @@ -21,7 +21,7 @@ NMPCache *nm_platform_get_cache(NMPlatform *self); } \ G_STMT_END -void nm_platform_cache_update_emit_signal(NMPlatform * platform, +void nm_platform_cache_update_emit_signal(NMPlatform *platform, NMPCacheOpsType cache_op, const NMPObject *obj_old, const NMPObject *obj_new); diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c index f0522736..9ad030df 100644 --- a/src/libnm-platform/nm-platform-utils.c +++ b/src/libnm-platform/nm-platform-utils.c @@ -91,16 +91,16 @@ typedef enum { } IoctlCallDataType; static int -_ioctl_call(const char * log_ioctl_type, - const char * log_subtype, +_ioctl_call(const char *log_ioctl_type, + const char *log_subtype, unsigned long int ioctl_request, int ifindex, - int * inout_fd, - char * inout_ifname, + int *inout_fd, + char *inout_ifname, IoctlCallDataType edata_type, gpointer edata, gsize edata_size, - struct ifreq * out_ifreq) + struct ifreq *out_ifreq) { nm_auto_close int fd_close = -1; int fd; @@ -109,7 +109,7 @@ _ioctl_call(const char * log_ioctl_type, gs_free gpointer edata_backup_free = NULL; guint try_count; char known_ifnames[2][IFNAMSIZ]; - const char * failure_reason = NULL; + const char *failure_reason = NULL; struct ifreq ifr; nm_assert(ifindex > 0); @@ -365,7 +365,7 @@ ethtool_get_stringset(SocketHandle *shandle, int stringset_id) .info.reserved = 0, .info.sset_mask = (1ULL << stringset_id), }; - const guint32 * pdata; + const guint32 *pdata; gs_free struct ethtool_gstrings *gstrings = NULL; gsize gstrings_len; guint32 i, len; @@ -574,7 +574,7 @@ _ASSERT_ethtool_feature_infos(void) static NMEthtoolFeatureStates * ethtool_get_features(SocketHandle *shandle) { - gs_free NMEthtoolFeatureStates * states = NULL; + gs_free NMEthtoolFeatureStates *states = NULL; gs_free struct ethtool_gstrings *ss_features = NULL; _ASSERT_ethtool_feature_infos(); @@ -584,11 +584,11 @@ ethtool_get_features(SocketHandle *shandle) return NULL; if (ss_features->len > 0) { - gs_free struct ethtool_gfeatures * gfeatures_free = NULL; - struct ethtool_gfeatures * gfeatures; + gs_free struct ethtool_gfeatures *gfeatures_free = NULL; + struct ethtool_gfeatures *gfeatures; gsize gfeatures_len; guint idx; - const NMEthtoolFeatureState * states_list0 = NULL; + const NMEthtoolFeatureState *states_list0 = NULL; const NMEthtoolFeatureState *const *states_plist0 = NULL; guint states_plist_n = 0; @@ -606,7 +606,7 @@ ethtool_get_features(SocketHandle *shandle) for (idx_kernel_name = 0; idx_kernel_name < info->n_kernel_names; idx_kernel_name++) { NMEthtoolFeatureState *kstate; - const char * kernel_name = info->kernel_names[idx_kernel_name]; + const char *kernel_name = info->kernel_names[idx_kernel_name]; int i_feature; guint i_block; guint32 i_flag; @@ -667,7 +667,7 @@ NMEthtoolFeatureStates * nmp_utils_ethtool_get_features(int ifindex) { nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); - NMEthtoolFeatureStates * features; + NMEthtoolFeatureStates *features; g_return_val_if_fail(ifindex > 0, 0); @@ -689,10 +689,10 @@ nmp_utils_ethtool_get_features(int ifindex) } static const char * -_ethtool_feature_state_to_string(char * buf, +_ethtool_feature_state_to_string(char *buf, gsize buf_size, const NMEthtoolFeatureState *s, - const char * prefix) + const char *prefix) { int l; @@ -718,8 +718,8 @@ nmp_utils_ethtool_set_features( gboolean do_set /* or reset */) { nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); - gs_free struct ethtool_sfeatures * sfeatures_free = NULL; - struct ethtool_sfeatures * sfeatures; + gs_free struct ethtool_sfeatures *sfeatures_free = NULL; + struct ethtool_sfeatures *sfeatures; gsize sfeatures_len; int r; guint i, j; @@ -1215,8 +1215,8 @@ gboolean nmp_utils_ethtool_supports_vlans(int ifindex) { nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); - gs_free struct ethtool_gfeatures * features_free = NULL; - struct ethtool_gfeatures * features; + gs_free struct ethtool_gfeatures *features_free = NULL; + struct ethtool_gfeatures *features; gsize features_len; int idx, block, bit, size; @@ -1250,8 +1250,8 @@ nmp_utils_ethtool_get_peer_ifindex(int ifindex) { nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); gsize stats_len; - gs_free struct ethtool_stats * stats_free = NULL; - struct ethtool_stats * stats; + gs_free struct ethtool_stats *stats_free = NULL; + struct ethtool_stats *stats; int peer_ifindex_stat; g_return_val_if_fail(ifindex > 0, 0); @@ -1289,8 +1289,8 @@ nmp_utils_ethtool_get_wake_on_lan(int ifindex) gboolean nmp_utils_ethtool_get_link_settings(int ifindex, - gboolean * out_autoneg, - guint32 * out_speed, + gboolean *out_autoneg, + guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex) { struct ethtool_cmd edata = { @@ -1474,7 +1474,7 @@ const guint32 _nmp_link_mode_all_advertised_modes[] = { }; static NMOptionBool -set_link_settings_new(SocketHandle * shandle, +set_link_settings_new(SocketHandle *shandle, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex) @@ -1512,8 +1512,8 @@ set_link_settings_new(SocketHandle * shandle, { const guint32 *v_map_supported = &edata->link_mode_masks[0]; - guint32 * v_map_advertising = &edata->link_mode_masks[nwords]; - guint32 * v_map_lp_advertising = &edata->link_mode_masks[2 * nwords]; + guint32 *v_map_advertising = &edata->link_mode_masks[nwords]; + guint32 *v_map_lp_advertising = &edata->link_mode_masks[2 * nwords]; memcpy(v_map_advertising, v_map_supported, sizeof(guint32) * nwords); (void) v_map_lp_advertising; @@ -1574,7 +1574,7 @@ nmp_utils_ethtool_set_link_settings(int ifindex, { nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); struct ethtool_cmd edata = { - .cmd = ETHTOOL_GSET, + .cmd = ETHTOOL_GSET, }; NMOptionBool ret; @@ -1651,7 +1651,7 @@ set_autoneg: gboolean nmp_utils_ethtool_set_wake_on_lan(int ifindex, _NMSettingWiredWakeOnLan wol, - const char * wol_password) + const char *wol_password) { struct ethtool_wolinfo wol_info = { .cmd = ETHTOOL_SWOL, @@ -1706,7 +1706,7 @@ nmp_utils_mii_supports_carrier_detect(int ifindex) nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); int r; struct ifreq ifr; - struct mii_ioctl_data * mii; + struct mii_ioctl_data *mii; g_return_val_if_fail(ifindex > 0, FALSE); @@ -1757,7 +1757,7 @@ const char * nmp_utils_udev_get_driver(struct udev_device *udevice) { struct udev_device *parent = NULL, *grandparent = NULL; - const char * driver, *subsys; + const char *driver, *subsys; driver = udev_device_get_driver(udevice); if (driver) @@ -2194,10 +2194,10 @@ nmp_utils_modprobe(GError **error, gboolean suppress_error_logging, const char * { gs_unref_ptrarray GPtrArray *argv = NULL; int exit_status; - gs_free char * _log_str = NULL; + gs_free char *_log_str = NULL; #define ARGV_TO_STR(argv) \ (_log_str ? _log_str : (_log_str = g_strjoinv(" ", (char **) argv->pdata))) - GError * local = NULL; + GError *local = NULL; va_list ap; NMLogLevel llevel = suppress_error_logging ? LOGL_DEBUG : LOGL_ERR; gs_free char *std_out = NULL, *std_err = NULL; diff --git a/src/libnm-platform/nm-platform-utils.h b/src/libnm-platform/nm-platform-utils.h index 5511e8af..a9ccebb3 100644 --- a/src/libnm-platform/nm-platform-utils.h +++ b/src/libnm-platform/nm-platform-utils.h @@ -18,7 +18,7 @@ int nmp_utils_ethtool_get_peer_ifindex(int ifindex); gboolean nmp_utils_ethtool_get_wake_on_lan(int ifindex); gboolean nmp_utils_ethtool_set_wake_on_lan(int ifindex, _NMSettingWiredWakeOnLan wol, - const char * wol_password); + const char *wol_password); const char *nm_platform_link_duplex_type_to_string(NMPlatformLinkDuplexType duplex); @@ -26,8 +26,8 @@ extern const guint8 _nmp_link_mode_all_advertised_modes_bits[79]; extern const guint32 _nmp_link_mode_all_advertised_modes[3]; gboolean nmp_utils_ethtool_get_link_settings(int ifindex, - gboolean * out_autoneg, - guint32 * out_speed, + gboolean *out_autoneg, + guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); gboolean nmp_utils_ethtool_set_link_settings(int ifindex, gboolean autoneg, @@ -77,7 +77,7 @@ int nmp_utils_if_nametoindex(const char *ifname); int nmp_utils_sysctl_open_netdir(int ifindex, const char *ifname_guess, char *out_ifname); -char * nmp_utils_new_vlan_name(const char *parent_iface, guint32 vlan_id); +char *nmp_utils_new_vlan_name(const char *parent_iface, guint32 vlan_id); const char *nmp_utils_new_infiniband_name(char *name, const char *parent_name, int p_key); guint32 diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 5d4ec037..b95cd95e 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -115,9 +115,9 @@ nmp_link_address_get_as_bytes(const NMPLinkAddress *addr) #define NMLOG_COMMON(level, name, ...) \ char __prefix[32]; \ - const char * __p_prefix = _NMLOG_PREFIX_NAME; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ const NMPlatform *const __self = (self); \ - const char * __name = name; \ + const char *__name = name; \ \ if (__self && NM_PLATFORM_GET_PRIVATE(__self)->log_with_ptr) { \ g_snprintf(__prefix, sizeof(__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ @@ -187,9 +187,9 @@ typedef struct _NMPlatformPrivate { guint ip4_dev_route_blacklist_check_id; guint ip4_dev_route_blacklist_gc_timeout_id; - GHashTable * ip4_dev_route_blacklist_hash; + GHashTable *ip4_dev_route_blacklist_hash; NMDedupMultiIndex *multi_idx; - NMPCache * cache; + NMPCache *cache; } NMPlatformPrivate; G_DEFINE_TYPE(NMPlatform, nm_platform, G_TYPE_OBJECT) @@ -255,7 +255,7 @@ _nm_platform_signal_id_get(NMPlatformSignalIdType signal_type) #define _CHECK_SELF_NETNS(self, klass, netns, err_val) \ nm_auto_pop_netns NMPNetns *netns = NULL; \ - NMPlatformClass * klass; \ + NMPlatformClass *klass; \ do { \ g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \ klass = NM_PLATFORM_GET_CLASS(self); \ @@ -531,14 +531,14 @@ nm_platform_sysctl_set(NMPlatform *self, * independently of how /proc/sys/kernel/sysctl_writes_strict is configured. */ void -nm_platform_sysctl_set_async(NMPlatform * self, - const char * pathid, +nm_platform_sysctl_set_async(NMPlatform *self, + const char *pathid, int dirfd, - const char * path, - const char *const * values, + const char *path, + const char *const *values, NMPlatformAsyncCallback callback, gpointer data, - GCancellable * cancellable) + GCancellable *cancellable) { _CHECK_SELF_VOID(self, klass); @@ -717,7 +717,7 @@ nm_platform_sysctl_get_int_checked(NMPlatform *self, gint64 max, gint64 fallback) { - char * value = NULL; + char *value = NULL; gint32 ret; int errsv; @@ -821,7 +821,7 @@ int nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(NMPlatform *self, const char *ifname, gboolean consider_all, - gboolean * out_due_to_all) + gboolean *out_due_to_all) { int val, val_all; @@ -899,11 +899,11 @@ _link_get_all_presort(gconstpointer p_a, gconstpointer p_b, gpointer sort_by_nam GPtrArray * nm_platform_link_get_all(NMPlatform *self, gboolean sort_by_name) { - gs_unref_ptrarray GPtrArray *links = NULL; - GPtrArray * result; - guint i, nresult; + gs_unref_ptrarray GPtrArray *links = NULL; + GPtrArray *result; + guint i, nresult; gs_unref_hashtable GHashTable *unseen = NULL; - const NMPlatformLink * item; + const NMPlatformLink *item; NMPLookup lookup; _CHECK_SELF(self, klass, NULL); @@ -1077,7 +1077,7 @@ struct _nm_platform_link_get_by_address_data { }; static gboolean -_nm_platform_link_get_by_address_match_link(const NMPObject * obj, +_nm_platform_link_get_by_address_match_link(const NMPObject *obj, struct _nm_platform_link_get_by_address_data *d) { return obj->link.l_address.len == d->len && !memcmp(obj->link.l_address.data, d->data, d->len); @@ -1093,12 +1093,12 @@ _nm_platform_link_get_by_address_match_link(const NMPObject * * address. **/ const NMPlatformLink * -nm_platform_link_get_by_address(NMPlatform * self, +nm_platform_link_get_by_address(NMPlatform *self, NMLinkType link_type, gconstpointer address, size_t length) { - const NMPObject * obj; + const NMPObject *obj; struct _nm_platform_link_get_by_address_data d = { .data = address, .len = length, @@ -1125,8 +1125,8 @@ nm_platform_link_get_by_address(NMPlatform * self, } static int -_link_add_check_existing(NMPlatform * self, - const char * name, +_link_add_check_existing(NMPlatform *self, + const char *name, NMLinkType type, const NMPlatformLink **out_link) { @@ -1174,11 +1174,11 @@ _link_add_check_existing(NMPlatform * self, * Returns: the negative nm-error on failure. */ int -nm_platform_link_add(NMPlatform * self, +nm_platform_link_add(NMPlatform *self, NMLinkType type, - const char * name, + const char *name, int parent, - const void * address, + const void *address, size_t address_len, guint32 mtu, gconstpointer extra_data, @@ -1439,13 +1439,13 @@ nm_platform_link_get_type_name(NMPlatform *self, int ifindex) } gboolean -nm_platform_link_get_udev_property(NMPlatform * self, +nm_platform_link_get_udev_property(NMPlatform *self, int ifindex, - const char * name, + const char *name, const char **out_value) { struct udev_device *udevice = NULL; - const char * uproperty; + const char *uproperty; udevice = nm_platform_link_get_udev_device(self, ifindex); if (!udevice) @@ -1717,7 +1717,7 @@ nm_platform_link_get_address(NMPlatform *self, int ifindex, size_t *length) * address. */ gboolean -nm_platform_link_get_permanent_address_ethtool(NMPlatform * self, +nm_platform_link_get_permanent_address_ethtool(NMPlatform *self, int ifindex, NMPLinkAddress *out_address) { @@ -1735,9 +1735,9 @@ nm_platform_link_get_permanent_address_ethtool(NMPlatform * self, } gboolean -nm_platform_link_get_permanent_address(NMPlatform * self, +nm_platform_link_get_permanent_address(NMPlatform *self, const NMPlatformLink *plink, - NMPLinkAddress * out_address) + NMPLinkAddress *out_address) { _CHECK_SELF(self, klass, FALSE); nm_assert(out_address); @@ -1804,13 +1804,13 @@ nm_platform_link_supports_sriov(NMPlatform *self, int ifindex) * always invoked, and asynchronously. */ void -nm_platform_link_set_sriov_params_async(NMPlatform * self, +nm_platform_link_set_sriov_params_async(NMPlatform *self, int ifindex, guint num_vfs, NMOptionBool autoprobe, NMPlatformAsyncCallback callback, gpointer callback_data, - GCancellable * cancellable) + GCancellable *cancellable) { _CHECK_SELF_VOID(self, klass); @@ -1845,7 +1845,7 @@ nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF } gboolean -nm_platform_link_set_bridge_vlans(NMPlatform * self, +nm_platform_link_set_bridge_vlans(NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans) @@ -2038,9 +2038,9 @@ nm_platform_link_get_wake_on_lan(NMPlatform *self, int ifindex) gboolean nm_platform_link_get_driver_info(NMPlatform *self, int ifindex, - char ** out_driver_name, - char ** out_driver_version, - char ** out_fw_version) + char **out_driver_name, + char **out_driver_version, + char **out_fw_version) { _CHECK_SELF(self, klass, FALSE); @@ -2149,7 +2149,7 @@ nm_platform_link_can_assume(NMPlatform *self, int ifindex) * (but don't modify it). */ const NMPObject * -nm_platform_link_get_lnk(NMPlatform * self, +nm_platform_link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link) @@ -2308,10 +2308,10 @@ static NM_UTILS_FLAGS2STR_DEFINE( NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS, "remove-aips"), ); int -nm_platform_link_wireguard_change(NMPlatform * self, +nm_platform_link_wireguard_change(NMPlatform *self, int ifindex, - const NMPlatformLnkWireGuard * lnk_wireguard, - const NMPWireGuardPeer * peers, + const NMPlatformLnkWireGuard *lnk_wireguard, + const NMPWireGuardPeer *peers, const NMPlatformWireGuardChangePeerFlags *peer_flags, guint peers_len, NMPlatformWireGuardChangeFlags change_flags) @@ -2391,11 +2391,11 @@ nm_platform_link_wireguard_change(NMPlatform * self * Create a TUN or TAP interface. */ int -nm_platform_link_tun_add(NMPlatform * self, - const char * name, +nm_platform_link_tun_add(NMPlatform *self, + const char *name, const NMPlatformLnkTun *props, - const NMPlatformLink ** out_link, - int * out_fd) + const NMPlatformLink **out_link, + int *out_fd) { char b[255]; int r; @@ -2466,7 +2466,7 @@ link_set_option(NMPlatform *self, { nm_auto_close int dirfd = -1; char ifname_verified[IFNAMSIZ]; - const char * path; + const char *path; if (!category || !option) return FALSE; @@ -2487,7 +2487,7 @@ link_get_option(NMPlatform *self, int ifindex, const char *category, const char { nm_auto_close int dirfd = -1; char ifname_verified[IFNAMSIZ]; - const char * path; + const char *path; if (!category || !option) return NULL; @@ -2588,7 +2588,7 @@ nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *o /*****************************************************************************/ gboolean -nm_platform_link_vlan_change(NMPlatform * self, +nm_platform_link_vlan_change(NMPlatform *self, int ifindex, _NMVlanFlags flags_mask, _NMVlanFlags flags_set, @@ -2680,7 +2680,7 @@ nm_platform_link_vlan_set_egress_map(NMPlatform *self, int ifindex, int from, in } static int -_infiniband_add_add_or_delete(NMPlatform * self, +_infiniband_add_add_or_delete(NMPlatform *self, int ifindex, int p_key, gboolean add, @@ -2727,7 +2727,7 @@ _infiniband_add_add_or_delete(NMPlatform * self, } int -nm_platform_link_infiniband_add(NMPlatform * self, +nm_platform_link_infiniband_add(NMPlatform *self, int parent, int p_key, const NMPlatformLink **out_link) @@ -2742,18 +2742,18 @@ nm_platform_link_infiniband_delete(NMPlatform *self, int parent, int p_key) } gboolean -nm_platform_link_infiniband_get_properties(NMPlatform * self, +nm_platform_link_infiniband_get_properties(NMPlatform *self, int ifindex, - int * out_parent, - int * out_p_key, + int *out_parent, + int *out_p_key, const char **out_mode) { nm_auto_close int dirfd = -1; char ifname_verified[IFNAMSIZ]; const NMPlatformLnkInfiniband *plnk; - const NMPlatformLink * plink; - char * contents; - const char * mode; + const NMPlatformLink *plink; + char *contents; + const char *mode; int p_key = 0; _CHECK_SELF(self, klass, FALSE); @@ -2968,11 +2968,11 @@ nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex) } gboolean -nm_platform_wifi_get_station(NMPlatform * self, +nm_platform_wifi_get_station(NMPlatform *self, int ifindex, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate) + int *out_quality, + guint32 *out_rate) { _CHECK_SELF(self, klass, FALSE); @@ -3143,11 +3143,12 @@ nm_platform_wpan_set_channel(NMPlatform *self, int ifindex, guint8 page, guint8 static const char * _to_string_dev(NMPlatform *self, int ifindex, char *buf, size_t size) { - g_assert(buf && size >= TO_STRING_DEV_BUF_SIZE); + nm_assert(buf); + nm_assert(size >= TO_STRING_DEV_BUF_SIZE); if (ifindex) { const char *name = ifindex > 0 && self ? nm_platform_link_get_name(self, ifindex) : NULL; - char * buf2; + char *buf2; strcpy(buf, " dev "); buf2 = buf + 5; @@ -3188,10 +3189,10 @@ _to_string_ifa_flags(guint32 ifa_flags, char *buf, gsize size) /*****************************************************************************/ gboolean -nm_platform_ethtool_set_wake_on_lan(NMPlatform * self, +nm_platform_ethtool_set_wake_on_lan(NMPlatform *self, int ifindex, _NMSettingWiredWakeOnLan wol, - const char * wol_password) + const char *wol_password) { _CHECK_SELF_NETNS(self, klass, netns, FALSE); @@ -3201,7 +3202,7 @@ nm_platform_ethtool_set_wake_on_lan(NMPlatform * self, } gboolean -nm_platform_ethtool_set_link_settings(NMPlatform * self, +nm_platform_ethtool_set_link_settings(NMPlatform *self, int ifindex, gboolean autoneg, guint32 speed, @@ -3215,10 +3216,10 @@ nm_platform_ethtool_set_link_settings(NMPlatform * self, } gboolean -nm_platform_ethtool_get_link_settings(NMPlatform * self, +nm_platform_ethtool_get_link_settings(NMPlatform *self, int ifindex, - gboolean * out_autoneg, - guint32 * out_speed, + gboolean *out_autoneg, + guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex) { _CHECK_SELF_NETNS(self, klass, netns, FALSE); @@ -3242,7 +3243,7 @@ nm_platform_ethtool_get_link_features(NMPlatform *self, int ifindex) gboolean nm_platform_ethtool_set_features( - NMPlatform * self, + NMPlatform *self, int ifindex, const NMEthtoolFeatureStates *features, const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, @@ -3256,7 +3257,7 @@ nm_platform_ethtool_set_features( } gboolean -nm_platform_ethtool_get_link_coalesce(NMPlatform * self, +nm_platform_ethtool_get_link_coalesce(NMPlatform *self, int ifindex, NMEthtoolCoalesceState *coalesce) { @@ -3269,7 +3270,7 @@ nm_platform_ethtool_get_link_coalesce(NMPlatform * self, } gboolean -nm_platform_ethtool_set_coalesce(NMPlatform * self, +nm_platform_ethtool_set_coalesce(NMPlatform *self, int ifindex, const NMEthtoolCoalesceState *coalesce) { @@ -3380,8 +3381,8 @@ nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel(const NMPObject *obj * Returns: the result of the lookup. */ GPtrArray * -nm_platform_lookup_clone(NMPlatform * self, - const NMPLookup * lookup, +nm_platform_lookup_clone(NMPlatform *self, + const NMPLookup *lookup, NMPObjectPredicateFunc predicate, gpointer user_data) { @@ -3511,7 +3512,7 @@ nm_platform_ip4_address_add(NMPlatform *self, } gboolean -nm_platform_ip6_address_add(NMPlatform * self, +nm_platform_ip6_address_add(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen, @@ -3630,7 +3631,7 @@ nm_platform_ip6_address_get(NMPlatform *self, int ifindex, const struct in6_addr static gboolean _addr_array_clean_expired(int addr_family, int ifindex, - GPtrArray * array, + GPtrArray *array, guint32 now, GHashTable **idx) { @@ -3748,7 +3749,7 @@ ip4_addr_subnets_build_index(const GPtrArray *addresses, for (i = 0; i < addresses->len; i++) { const NMPlatformIP4Address *address; gpointer p_address; - GPtrArray * addr_list; + GPtrArray *addr_list; guint32 net; int position; gpointer p; @@ -3805,16 +3806,16 @@ ip4_addr_subnets_build_index(const GPtrArray *addresses, * Returns: %TRUE if the address is secondary, %FALSE otherwise */ static gboolean -ip4_addr_subnets_is_secondary(const NMPObject * address, - GHashTable * subnets, - const GPtrArray * addresses, +ip4_addr_subnets_is_secondary(const NMPObject *address, + GHashTable *subnets, + const GPtrArray *addresses, const GPtrArray **out_addr_list) { const NMPlatformIP4Address *a; - const GPtrArray * addr_list; + const GPtrArray *addr_list; gconstpointer p; guint32 net; - const NMPObject ** o; + const NMPObject **o; a = NMP_OBJECT_CAST_IP4_ADDRESS(address); @@ -3902,14 +3903,14 @@ gboolean nm_platform_ip_address_sync(NMPlatform *self, int addr_family, int ifindex, - GPtrArray * known_addresses, - GPtrArray * addresses_prune) + GPtrArray *known_addresses, + GPtrArray *addresses_prune) { - const gint32 now = nm_utils_get_monotonic_timestamp_sec(); - const int IS_IPv4 = NM_IS_IPv4(addr_family); + const gint32 now = nm_utils_get_monotonic_timestamp_sec(); + const int IS_IPv4 = NM_IS_IPv4(addr_family); gs_unref_hashtable GHashTable *known_addresses_idx = NULL; - GPtrArray * plat_addresses; - GHashTable * known_subnets = NULL; + GPtrArray *plat_addresses; + GHashTable *known_subnets = NULL; guint i_plat; guint i_know; guint i; @@ -3947,9 +3948,9 @@ nm_platform_ip_address_sync(NMPlatform *self, plat_subnets = ip4_addr_subnets_build_index(plat_addresses, TRUE, TRUE); for (i = 0; i < plat_addresses->len; i++) { - const NMPObject * plat_obj; + const NMPObject *plat_obj; const NMPlatformIP4Address *plat_address; - const GPtrArray * addr_list; + const GPtrArray *addr_list; plat_obj = plat_addresses->pdata[i]; if (!plat_obj) { @@ -4044,8 +4045,8 @@ nm_platform_ip_address_sync(NMPlatform *self, * * Note that we mark handled addresses by setting it to %NULL in @plat_addresses array. */ for (i_plat = 0; i_plat < plat_addresses->len; i_plat++) { - const NMPObject * plat_obj = plat_addresses->pdata[i_plat]; - const NMPObject * know_obj; + const NMPObject *plat_obj = plat_addresses->pdata[i_plat]; + const NMPObject *know_obj; const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj); if (known_addresses_idx) { @@ -4141,7 +4142,7 @@ next_plat:; */ for (i_know = 0; i_know < known_addresses->len; i_know++) { const NMPlatformIPXAddress *known_address; - const NMPObject * o; + const NMPObject *o; guint32 lifetime; guint32 preferred; @@ -4211,7 +4212,7 @@ nm_platform_ip_address_flush(NMPlatform *self, int addr_family, int ifindex) static gboolean _err_inval_due_to_ipv6_tentative_pref_src(NMPlatform *self, const NMPObject *obj) { - const NMPlatformIP6Route * r; + const NMPlatformIP6Route *r; const NMPlatformIP6Address *a; nm_assert(NM_IS_PLATFORM(self)); @@ -4253,8 +4254,8 @@ nm_platform_ip_address_get_prune_list(NMPlatform *self, const int IS_IPv4 = NM_IS_IPv4(addr_family); const NMDedupMultiHeadEntry *head_entry; NMPLookup lookup; - GPtrArray * result; - CList * iter; + GPtrArray *result; + CList *iter; nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(NM_IS_IPv4(addr_family)), ifindex); @@ -4285,20 +4286,20 @@ nm_platform_ip_address_get_prune_list(NMPlatform *self, } GPtrArray * -nm_platform_ip_route_get_prune_list(NMPlatform * self, +nm_platform_ip_route_get_prune_list(NMPlatform *self, int addr_family, int ifindex, NMIPRouteTableSyncMode route_table_sync) { NMPLookup lookup; - GPtrArray * routes_prune; + GPtrArray *routes_prune; const NMDedupMultiHeadEntry *head_entry; - CList * iter; + CList *iter; NMPlatformIP4Route rt_local4; NMPlatformIP6Route rt_local6; NMPlatformIP6Route rt_mcast6; - const NMPlatformLink * pllink; - const NMPlatformLnkVrf * lnk_vrf; + const NMPlatformLink *pllink; + const NMPlatformLnkVrf *lnk_vrf; guint32 local_table; nm_assert(NM_IS_PLATFORM(self)); @@ -4326,7 +4327,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self, routes_prune = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref); c_list_for_each (iter, &head_entry->lst_entries_head) { - const NMPObject * obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; const NMPlatformIPXRoute *rt = NMP_OBJECT_CAST_IPX_ROUTE(obj); switch (route_table_sync) { @@ -4493,15 +4494,15 @@ gboolean nm_platform_ip_route_sync(NMPlatform *self, int addr_family, int ifindex, - GPtrArray * routes, - GPtrArray * routes_prune, + GPtrArray *routes, + GPtrArray *routes_prune, GPtrArray **out_temporary_not_available) { - const int IS_IPv4 = NM_IS_IPv4(addr_family); - const NMPlatformVTableRoute *vt; + const int IS_IPv4 = NM_IS_IPv4(addr_family); + const NMPlatformVTableRoute *vt; gs_unref_hashtable GHashTable *routes_idx = NULL; - const NMPObject * conf_o; - const NMDedupMultiEntry * plat_entry; + const NMPObject *conf_o; + const NMDedupMultiEntry *plat_entry; guint i; int i_type; gboolean success = TRUE; @@ -4520,12 +4521,6 @@ nm_platform_ip_route_sync(NMPlatform *self, conf_o = routes->pdata[i]; - if (NMP_OBJECT_CAST_IP_ROUTE(conf_o)->is_external) { - /* This route is added externally. We don't have our own agenda to - * add it, so skip. */ - continue; - } - /* User space cannot add IPv6 routes with metric 0. However, kernel can, and we might track such * routes in @route as they are present external. As we already skipped external routes above, * we don't expect a user's choice to add such a route (it won't work anyway). */ @@ -4721,24 +4716,6 @@ sync_route_add: } if (routes_prune) { - if (routes) { - for (i = 0; i < routes->len; i++) { - conf_o = routes->pdata[i]; - - if (NMP_OBJECT_CAST_IP_ROUTE(conf_o)->is_external) { - /* this is only to catch the case where an external route is - * both in @routes and @routes_prune list. In that case, - * @routes should win and we should not remove the address. */ - if (!routes_idx) { - routes_idx = g_hash_table_new((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); - } - g_hash_table_add(routes_idx, (gpointer) conf_o); - continue; - } - } - } - for (i = 0; i < routes_prune->len; i++) { const NMPObject *prune_o; @@ -4958,11 +4935,11 @@ nm_platform_object_delete(NMPlatform *self, const NMPObject *obj) /*****************************************************************************/ int -nm_platform_ip_route_get(NMPlatform * self, +nm_platform_ip_route_get(NMPlatform *self, int addr_family, gconstpointer address /* in_addr_t or struct in6_addr */, int oif_ifindex, - NMPObject ** out_route) + NMPObject **out_route) { nm_auto_nmpobj NMPObject *route = NULL; int result; @@ -5027,11 +5004,11 @@ _ip4_dev_route_blacklist_timeout_ms_marked(gint64 timeout_msec) static gboolean _ip4_dev_route_blacklist_check_cb(gpointer user_data) { - NMPlatform * self = user_data; + NMPlatform *self = user_data; NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); GHashTableIter iter; - const NMPObject * p_obj; - gint64 * p_timeout_ms; + const NMPObject *p_obj; + gint64 *p_timeout_ms; gint64 now_ms; priv->ip4_dev_route_blacklist_check_id = 0; @@ -5081,8 +5058,8 @@ static void _ip4_dev_route_blacklist_notify_route(NMPlatform *self, const NMPObject *obj) { NMPlatformPrivate *priv; - const NMPObject * p_obj; - gint64 * p_timeout_ms; + const NMPObject *p_obj; + gint64 *p_timeout_ms; gint64 now_ms; nm_assert(NM_IS_PLATFORM(self)); @@ -5120,11 +5097,11 @@ _ip4_dev_route_blacklist_notify_route(NMPlatform *self, const NMPObject *obj) static gboolean _ip4_dev_route_blacklist_gc_timeout_handle(gpointer user_data) { - NMPlatform * self = user_data; + NMPlatform *self = user_data; NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); GHashTableIter iter; - const NMPObject * p_obj; - gint64 * p_timeout_ms; + const NMPObject *p_obj; + gint64 *p_timeout_ms; gint64 now_ms; nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id); @@ -5193,15 +5170,15 @@ _ip4_dev_route_blacklist_schedule(NMPlatform *self) void nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self, int ifindex, - GPtrArray * ip4_dev_route_blacklist) + GPtrArray *ip4_dev_route_blacklist) { NMPlatformPrivate *priv; GHashTableIter iter; - const NMPObject * p_obj; + const NMPObject *p_obj; guint i; gint64 timeout_msec; gint64 timeout_msec_val; - gint64 * p_timeout_ms; + gint64 *p_timeout_ms; gboolean needs_check = FALSE; nm_assert(NM_IS_PLATFORM(self)); @@ -5275,7 +5252,7 @@ nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self, /*****************************************************************************/ int -nm_platform_routing_rule_add(NMPlatform * self, +nm_platform_routing_rule_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformRoutingRule *routing_rule) { @@ -5355,8 +5332,8 @@ nm_platform_tfilter_delete(NMPlatform *self, int ifindex, guint32 parent, gboole gboolean nm_platform_tc_sync(NMPlatform *self, int ifindex, - GPtrArray * known_qdiscs, - GPtrArray * known_tfilters) + GPtrArray *known_qdiscs, + GPtrArray *known_tfilters) { guint i; gboolean success = TRUE; @@ -5397,10 +5374,10 @@ nm_platform_tc_sync(NMPlatform *self, /*****************************************************************************/ const char * -nm_platform_vlan_qos_mapping_to_string(const char * name, +nm_platform_vlan_qos_mapping_to_string(const char *name, const NMVlanQosMapping *map, gsize n_map, - char * buf, + char *buf, gsize len) { gsize i; @@ -5448,7 +5425,7 @@ _lifetime_summary_to_string(gint32 now, guint32 timestamp, guint32 preferred, guint32 lifetime, - char * buf, + char *buf, size_t buf_size) { g_snprintf(buf, @@ -5478,7 +5455,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) char parent[20]; char str_flags[1 + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 1]; char str_highlighted_flags[50]; - char * s; + char *s; gsize l; char str_addrmode[30]; char str_address[_NM_UTILS_HWADDR_LEN_MAX * 3]; @@ -6109,7 +6086,7 @@ nm_platform_lnk_vxlan_to_string(const NMPlatformLnkVxlan *lnk, char *buf, gsize const char * nm_platform_wireguard_peer_to_string(const NMPWireGuardPeer *peer, char *buf, gsize len) { - char * buf0 = buf; + char *buf0 = buf; gs_free char *public_key_b64 = NULL; char s_sockaddr[NM_UTILS_INET_ADDRSTRLEN + 100]; char s_endpoint[20 + sizeof(s_sockaddr)]; @@ -6214,7 +6191,7 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf char str_dev[TO_STRING_DEV_BUF_SIZE]; char str_label[32]; char str_lft[30], str_pref[30], str_time[50], s_source[50]; - char * str_peer = NULL; + char *str_peer = NULL; const char *str_lft_p, *str_pref_p, *str_time_p; gint32 now = nm_utils_get_monotonic_timestamp_sec(); in_addr_t broadcast_address; @@ -6273,9 +6250,9 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf "%s" /* flags */ "%s" /* label */ " src %s" - "%s" /* external */ "%s" /* a_acd_not_ready */ "%s" /* a_assume_config_once */ + "%s" /* a_force_commit */ "", s_address, address->plen, @@ -6293,9 +6270,9 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), str_label, nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), - address->external ? " ext" : "", address->a_acd_not_ready ? " ip4acd-not-ready" : "", - address->a_assume_config_once ? " assume-config-once" : ""); + address->a_assume_config_once ? " assume-config-once" : "", + address->a_force_commit ? " force-commit" : ""); g_free(str_peer); return buf; } @@ -6374,7 +6351,7 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf char s_peer[INET6_ADDRSTRLEN]; char str_lft[30], str_pref[30], str_time[50], s_source[50]; char str_dev[TO_STRING_DEV_BUF_SIZE]; - char * str_peer = NULL; + char *str_peer = NULL; const char *str_lft_p, *str_pref_p, *str_time_p; gint32 now = nm_utils_get_monotonic_timestamp_sec(); @@ -6415,8 +6392,8 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf buf, len, "%s/%d lft %s pref %s%s%s%s%s src %s" - "%s" /* external */ "%s" /* a_assume_config_once */ + "%s" /* a_force_commit */ "", s_address, address->plen, @@ -6427,8 +6404,8 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf str_dev, _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), - address->external ? " external" : "", - address->a_assume_config_once ? " assume-config-once" : ""); + address->a_assume_config_once ? " assume-config-once" : "", + address->a_force_commit ? " force-commit" : ""); g_free(str_peer); return buf; } @@ -6482,12 +6459,19 @@ _rtm_flags_to_string_full(char *buf, gsize buf_size, unsigned rtm_flags) const char * nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsize len) { - char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; + char s_network[INET_ADDRSTRLEN]; + char s_gateway[INET_ADDRSTRLEN]; char s_pref_src[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; char str_table[30]; - char str_scope[30], s_source[50]; - char str_tos[32], str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; + char str_scope[30]; + char s_source[50]; + char str_tos[32]; + char str_window[32]; + char str_cwnd[32]; + char str_initcwnd[32]; + char str_initrwnd[32]; + char str_mtu[32]; char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; char str_type[30]; char str_metric[30]; @@ -6496,7 +6480,11 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz return buf; inet_ntop(AF_INET, &route->network, s_network, sizeof(s_network)); - inet_ntop(AF_INET, &route->gateway, s_gateway, sizeof(s_gateway)); + + if (route->gateway == 0) + s_gateway[0] = '\0'; + else + inet_ntop(AF_INET, &route->gateway, s_gateway, sizeof(s_gateway)); _to_string_dev(NULL, route->ifindex, str_dev, sizeof(str_dev)); @@ -6506,21 +6494,22 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz "type %s " /* type */ "%s" /* table */ "%s/%d" - " via %s" + "%s%s" /* gateway */ "%s" " metric %s" - " mss %" G_GUINT32_FORMAT " rt-src %s" /* protocol */ - "%s" /* rtm_flags */ - "%s%s" /* scope */ - "%s%s" /* pref-src */ - "%s" /* tos */ - "%s" /* window */ - "%s" /* cwnd */ - "%s" /* initcwnd */ - "%s" /* initrwnd */ - "%s" /* mtu */ - "%s" /* is_external */ - "%s" /* r_assume_config_once */ + " mss %" G_GUINT32_FORMAT /* mss */ + " rt-src %s" /* protocol */ + "%s" /* rtm_flags */ + "%s%s" /* scope */ + "%s%s" /* pref-src */ + "%s" /* tos */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* mtu */ + "%s" /* r_assume_config_once */ + "%s" /* r_force_commit */ "", nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced), str_type), @@ -6533,6 +6522,7 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz : ""), s_network, route->plen, + s_gateway[0] ? " via " : "", s_gateway, str_dev, route->metric_any @@ -6577,8 +6567,8 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz route->lock_mtu ? "lock " : "", route->mtu) : "", - route->is_external ? " is-external" : "", - route->r_assume_config_once ? " assume-config-once" : ""); + route->r_assume_config_once ? " assume-config-once" : "", + route->r_force_commit ? " force-commit" : ""); return buf; } @@ -6620,7 +6610,11 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz return buf; inet_ntop(AF_INET6, &route->network, s_network, sizeof(s_network)); - inet_ntop(AF_INET6, &route->gateway, s_gateway, sizeof(s_gateway)); + + if (IN6_IS_ADDR_UNSPECIFIED(&route->gateway)) + s_gateway[0] = '\0'; + else + inet_ntop(AF_INET6, &route->gateway, s_gateway, sizeof(s_gateway)); if (IN6_IS_ADDR_UNSPECIFIED(&route->pref_src)) s_pref_src[0] = 0; @@ -6635,21 +6629,22 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz "type %s " /* type */ "%s" /* table */ "%s/%d" - " via %s" + "%s%s" /* gateway */ "%s" " metric %s" - " mss %" G_GUINT32_FORMAT " rt-src %s" /* protocol */ - "%s" /* source */ - "%s" /* rtm_flags */ - "%s%s" /* pref-src */ - "%s" /* window */ - "%s" /* cwnd */ - "%s" /* initcwnd */ - "%s" /* initrwnd */ - "%s" /* mtu */ - "%s" /* pref */ - "%s" /* is_external */ - "%s" /* r_assume_config_once */ + " mss %" G_GUINT32_FORMAT /* mss */ + " rt-src %s" /* protocol */ + "%s" /* source */ + "%s" /* rtm_flags */ + "%s%s" /* pref-src */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* mtu */ + "%s" /* pref */ + "%s" /* r_assume_config_once */ + "%s" /* r_force_commit */ "", nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced), str_type), @@ -6662,6 +6657,7 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz : ""), s_network, route->plen, + s_gateway[0] ? " via " : "", s_gateway, str_dev, route->metric_any @@ -6710,15 +6706,15 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz " pref %s", nm_icmpv6_router_pref_to_string(route->rt_pref, str_pref2, sizeof(str_pref2))) : "", - route->is_external ? " is-external" : "", - route->r_assume_config_once ? " assume-config-once" : ""); + route->r_assume_config_once ? " assume-config-once" : "", + route->r_force_commit ? " force-commit" : ""); return buf; } static void -_routing_rule_addr_to_string(char ** buf, - gsize * len, +_routing_rule_addr_to_string(char **buf, + gsize *len, int addr_family, const NMIPAddr *addr, guint8 plen, @@ -6752,10 +6748,10 @@ _routing_rule_addr_to_string(char ** buf, } static void -_routing_rule_port_range_to_string(char ** buf, - gsize * len, +_routing_rule_port_range_to_string(char **buf, + gsize *len, const NMFibRulePortRange *port_range, - const char * name) + const char *name) { if (port_range->start == 0 && port_range->end == 0) nm_strbuf_append_str(buf, len, ""); @@ -7179,11 +7175,11 @@ nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b) const char * nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len) { - char str_mac[128], mac[128]; - char str_spoof_check[64]; - char str_trust[64]; - char str_min_tx_rate[64]; - char str_max_tx_rate[64]; + char str_mac[128], mac[128]; + char str_spoof_check[64]; + char str_trust[64]; + char str_min_tx_rate[64]; + char str_max_tx_rate[64]; nm_auto_free_gstring GString *gstr_vlans = NULL; guint i; @@ -7845,10 +7841,10 @@ nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState obj->address, obj->peer_address, NM_HASH_COMBINE_BOOLS(guint8, - obj->external, obj->use_ip4_broadcast_address, obj->a_acd_not_ready, - obj->a_assume_config_once)); + obj->a_assume_config_once, + obj->a_force_commit)); nm_hash_update_strarr(h, obj->label); } @@ -7869,26 +7865,27 @@ nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, const NMPlatformIP4Ad NM_CMP_FIELD(a, b, preferred); NM_CMP_FIELD(a, b, n_ifa_flags); NM_CMP_FIELD_STR(a, b, label); - NM_CMP_FIELD_UNSAFE(a, b, external); NM_CMP_FIELD_UNSAFE(a, b, a_acd_not_ready); NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once); + NM_CMP_FIELD_UNSAFE(a, b, a_force_commit); return 0; } void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h) { - nm_hash_update_vals(h, - obj->ifindex, - obj->addr_source, - obj->timestamp, - obj->lifetime, - obj->preferred, - obj->n_ifa_flags, - obj->plen, - obj->address, - obj->peer_address, - NM_HASH_COMBINE_BOOLS(guint8, obj->external, obj->a_assume_config_once)); + nm_hash_update_vals( + h, + obj->ifindex, + obj->addr_source, + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address, + NM_HASH_COMBINE_BOOLS(guint8, obj->a_assume_config_once, obj->a_force_commit)); } int @@ -7908,15 +7905,15 @@ nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, const NMPlatformIP6Ad NM_CMP_FIELD(a, b, lifetime); NM_CMP_FIELD(a, b, preferred); NM_CMP_FIELD(a, b, n_ifa_flags); - NM_CMP_FIELD_UNSAFE(a, b, external); NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once); + NM_CMP_FIELD_UNSAFE(a, b, a_force_commit); return 0; } void nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, - NMHashState * h) + NMHashState *h) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: @@ -8018,8 +8015,8 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, obj->lock_initcwnd, obj->lock_initrwnd, obj->lock_mtu, - obj->is_external, - obj->r_assume_config_once)); + obj->r_assume_config_once, + obj->r_force_commit)); break; } } @@ -8110,8 +8107,8 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, NM_CMP_FIELD(a, b, initrwnd); NM_CMP_FIELD(a, b, mtu); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) { - NM_CMP_FIELD_UNSAFE(a, b, is_external); NM_CMP_FIELD_UNSAFE(a, b, r_assume_config_once); + NM_CMP_FIELD_UNSAFE(a, b, r_force_commit); } break; } @@ -8121,7 +8118,7 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, void nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, - NMHashState * h) + NMHashState *h) { struct in6_addr a1, a2; @@ -8205,8 +8202,8 @@ nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, obj->lock_initcwnd, obj->lock_initrwnd, obj->lock_mtu, - obj->is_external, - obj->r_assume_config_once), + obj->r_assume_config_once, + obj->r_force_commit), obj->window, obj->cwnd, obj->initcwnd, @@ -8290,8 +8287,8 @@ nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a, else NM_CMP_FIELD(a, b, rt_pref); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) { - NM_CMP_FIELD_UNSAFE(a, b, is_external); NM_CMP_FIELD_UNSAFE(a, b, r_assume_config_once); + NM_CMP_FIELD_UNSAFE(a, b, r_force_commit); } break; } @@ -8308,7 +8305,7 @@ nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a, void nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj, NMPlatformRoutingRuleCmpType cmp_type, - NMHashState * h) + NMHashState *h) { gboolean cmp_full = TRUE; gsize addr_size; @@ -8551,9 +8548,9 @@ nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex) { const NMDedupMultiHeadEntry *head_entry; NMDedupMultiIter iter; - const NMPObject * obj; + const NMPObject *obj; NMPLookup lookup; - GHashTable * hash; + GHashTable *hash; g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); g_return_val_if_fail(ifindex > 0, NULL); @@ -8583,7 +8580,8 @@ nm_platform_ip4_address_generate_device_route(const NMPlatformIP4Address *addr, int ifindex, guint32 route_table, guint32 route_metric, - NMPlatformIP4Route * dst) + gboolean force_commit, + NMPlatformIP4Route *dst) { in_addr_t network_4; @@ -8614,14 +8612,15 @@ nm_platform_ip4_address_generate_device_route(const NMPlatformIP4Address *addr, } *dst = (NMPlatformIP4Route){ - .ifindex = ifindex, - .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, - .network = network_4, - .plen = addr->plen, - .pref_src = addr->address, - .table_coerced = nm_platform_route_table_coerce(route_table), - .metric = route_metric, - .scope_inv = nm_platform_route_scope_inv(NM_RT_SCOPE_LINK), + .ifindex = ifindex, + .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, + .network = network_4, + .plen = addr->plen, + .pref_src = addr->address, + .table_coerced = nm_platform_route_table_coerce(route_table), + .metric = route_metric, + .scope_inv = nm_platform_route_scope_inv(NM_RT_SCOPE_LINK), + .r_force_commit = force_commit, }; nm_platform_ip_route_normalize(AF_INET, (NMPlatformIPRoute *) dst); @@ -8645,10 +8644,10 @@ nm_platform_signal_change_type_to_string(NMPlatformSignalChangeType change_type) } static void -log_link(NMPlatform * self, +log_link(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformLink * device, + NMPlatformLink *device, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8658,10 +8657,10 @@ log_link(NMPlatform * self, } static void -log_ip4_address(NMPlatform * self, +log_ip4_address(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformIP4Address * address, + NMPlatformIP4Address *address, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8671,10 +8670,10 @@ log_ip4_address(NMPlatform * self, } static void -log_ip6_address(NMPlatform * self, +log_ip6_address(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformIP6Address * address, + NMPlatformIP6Address *address, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8684,10 +8683,10 @@ log_ip6_address(NMPlatform * self, } static void -log_ip4_route(NMPlatform * self, +log_ip4_route(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformIP4Route * route, + NMPlatformIP4Route *route, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8697,10 +8696,10 @@ log_ip4_route(NMPlatform * self, } static void -log_ip6_route(NMPlatform * self, +log_ip6_route(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformIP6Route * route, + NMPlatformIP6Route *route, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8710,10 +8709,10 @@ log_ip6_route(NMPlatform * self, } static void -log_routing_rule(NMPlatform * self, +log_routing_rule(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformRoutingRule * routing_rule, + NMPlatformRoutingRule *routing_rule, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8724,10 +8723,10 @@ log_routing_rule(NMPlatform * self, } static void -log_qdisc(NMPlatform * self, +log_qdisc(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformQdisc * qdisc, + NMPlatformQdisc *qdisc, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8737,10 +8736,10 @@ log_qdisc(NMPlatform * self, } static void -log_tfilter(NMPlatform * self, +log_tfilter(NMPlatform *self, NMPObjectType obj_type, int ifindex, - NMPlatformTfilter * tfilter, + NMPlatformTfilter *tfilter, NMPlatformSignalChangeType change_type, gpointer user_data) { @@ -8752,7 +8751,7 @@ log_tfilter(NMPlatform * self, /*****************************************************************************/ void -nm_platform_cache_update_emit_signal(NMPlatform * self, +nm_platform_cache_update_emit_signal(NMPlatform *self, NMPCacheOpsType cache_op, const NMPObject *obj_old, const NMPObject *obj_new) @@ -8760,7 +8759,7 @@ nm_platform_cache_update_emit_signal(NMPlatform * self, gboolean visible_new; gboolean visible_old; const NMPObject *o; - const NMPClass * klass; + const NMPClass *klass; int ifindex; nm_assert(NM_IN_SET((NMPlatformSignalChangeType) cache_op, @@ -8875,7 +8874,7 @@ const _NMPlatformVTableRouteUnion nm_platform_vtable_route = { const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip4_route_cmp, .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, - char * buf, + char *buf, gsize len)) nm_platform_ip4_route_to_string, }, .v6 = @@ -8888,7 +8887,7 @@ const _NMPlatformVTableRouteUnion nm_platform_vtable_route = { const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip6_route_cmp, .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, - char * buf, + char *buf, gsize len)) nm_platform_ip6_route_to_string, }, }; @@ -8898,7 +8897,7 @@ const _NMPlatformVTableRouteUnion nm_platform_vtable_route = { static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMPlatform * self = NM_PLATFORM(object); + NMPlatform *self = NM_PLATFORM(object); NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); switch (prop_id) { @@ -8939,8 +8938,8 @@ nm_platform_init(NMPlatform *self) static GObject * constructor(GType type, guint n_construct_params, GObjectConstructParam *construct_params) { - GObject * object; - NMPlatform * self; + GObject *object; + NMPlatform *self; NMPlatformPrivate *priv; object = G_OBJECT_CLASS(nm_platform_parent_class) @@ -8958,7 +8957,7 @@ constructor(GType type, guint n_construct_params, GObjectConstructParam *constru static void finalize(GObject *object) { - NMPlatform * self = NM_PLATFORM(object); + NMPlatform *self = NM_PLATFORM(object); NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); nm_clear_g_source(&priv->ip4_dev_route_blacklist_check_id); diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 7101b48c..6f5cd524 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -155,7 +155,7 @@ G_STATIC_ASSERT(_nm_alignof(NMEtherAddr) == 1); G_STATIC_ASSERT(_nm_alignof(NMPLinkAddress) == 1); gconstpointer nmp_link_address_get(const NMPLinkAddress *addr, size_t *length); -GBytes * nmp_link_address_get_as_bytes(const NMPLinkAddress *addr); +GBytes *nmp_link_address_get_as_bytes(const NMPLinkAddress *addr); typedef enum { @@ -318,16 +318,14 @@ typedef enum { * IFA_FLAGS attribute. */ \ guint32 n_ifa_flags; \ \ - /* FIXME(l3cfg): the external marker won't be necessary anymore, because we only - * merge addresses we care about, and ignore (don't remove) external addresses. */ \ - bool external : 1; \ - \ bool use_ip4_broadcast_address : 1; \ \ - /* Whether the address is should be configured once during assume. This is a meta flag - * that is not honored by NMPlatform (netlink code). Instead, it can be used by the upper - * layers which use NMPlatformIPAddress to track addresses that should be configured. */ \ + /* Meta flags not honored by NMPlatform (netlink code). Instead, they can be + * used by the upper layers which use NMPlatformIPRoute to track addresses that + * should be configured. */ \ + /* Whether the address is should be configured once during assume. */ \ bool a_assume_config_once : 1; \ + bool a_force_commit : 1; \ \ guint8 plen; \ ; @@ -471,18 +469,13 @@ typedef union { * the "table_coerced" field is ignored (unlike for the metric). */ \ bool table_any : 1; \ \ - /* This route is tracked as external route, that is not a route that NetworkManager - * actively wants to add, but a route that was added externally. In some cases, such - * a route should be ignored. - * - * Note that unlike most other fields here, this flag only exists inside NetworkManager - * and is not reflected on netlink. */ \ - bool is_external : 1; \ - \ - /* Whether the route is should be configured once during assume. This is a meta flag - * that is not honored by NMPlatform (netlink code). Instead, it can be used by the upper - * layers which use NMPlatformIPRoute to track routes that should be configured. */ \ + /* Meta flags not honored by NMPlatform (netlink code). Instead, they can be + * used by the upper layers which use NMPlatformIPRoute to track routes that + * should be configured. */ \ + /* Whether the route is should be configured once during assume. */ \ bool r_assume_config_once : 1; \ + /* Whether the route should be committed even if it was removed externally. */ \ + bool r_force_commit : 1; \ \ /* rtnh_flags * @@ -1078,7 +1071,7 @@ struct _NMPlatformPrivate; struct _NMPlatform { GObject parent; - NMPNetns * _netns; + NMPNetns *_netns; struct _NMPlatformPrivate *_priv; }; @@ -1090,24 +1083,24 @@ typedef struct { int dirfd, const char *path, const char *value); - void (*sysctl_set_async)(NMPlatform * self, - const char * pathid, + void (*sysctl_set_async)(NMPlatform *self, + const char *pathid, int dirfd, - const char * path, - const char *const * values, + const char *path, + const char *const *values, NMPlatformAsyncCallback callback, gpointer data, - GCancellable * cancellable); + GCancellable *cancellable); char *(*sysctl_get)(NMPlatform *self, const char *pathid, int dirfd, const char *path); void (*refresh_all)(NMPlatform *self, NMPObjectType obj_type); void (*process_events)(NMPlatform *self); - int (*link_add)(NMPlatform * self, + int (*link_add)(NMPlatform *self, NMLinkType type, - const char * name, + const char *name, int parent, - const void * address, + const void *address, size_t address_len, guint32 mtu, gconstpointer extra_data, @@ -1123,21 +1116,21 @@ typedef struct { int (*link_set_inet6_addr_gen_mode)(NMPlatform *self, int ifindex, guint8 enabled); gboolean (*link_set_token)(NMPlatform *self, int ifindex, const NMUtilsIPv6IfaceId *iid); - gboolean (*link_get_permanent_address_ethtool)(NMPlatform * self, + gboolean (*link_get_permanent_address_ethtool)(NMPlatform *self, int ifindex, NMPLinkAddress *out_address); int (*link_set_address)(NMPlatform *self, int ifindex, gconstpointer address, size_t length); int (*link_set_mtu)(NMPlatform *self, int ifindex, guint32 mtu); gboolean (*link_set_name)(NMPlatform *self, int ifindex, const char *name); - void (*link_set_sriov_params_async)(NMPlatform * self, + void (*link_set_sriov_params_async)(NMPlatform *self, int ifindex, guint num_vfs, NMOptionBool autoprobe, NMPlatformAsyncCallback callback, gpointer callback_data, - GCancellable * cancellable); + GCancellable *cancellable); gboolean (*link_set_sriov_vfs)(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); - gboolean (*link_set_bridge_vlans)(NMPlatform * self, + gboolean (*link_set_bridge_vlans)(NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans); @@ -1147,9 +1140,9 @@ typedef struct { gboolean (*link_get_wake_on_lan)(NMPlatform *self, int ifindex); gboolean (*link_get_driver_info)(NMPlatform *self, int ifindex, - char ** out_driver_name, - char ** out_driver_version, - char ** out_fw_version); + char **out_driver_name, + char **out_driver_version, + char **out_fw_version); gboolean (*link_supports_carrier_detect)(NMPlatform *self, int ifindex); gboolean (*link_supports_vlans)(NMPlatform *self, int ifindex); @@ -1160,15 +1153,15 @@ typedef struct { gboolean (*link_can_assume)(NMPlatform *self, int ifindex); - int (*link_wireguard_change)(NMPlatform * self, + int (*link_wireguard_change)(NMPlatform *self, int ifindex, - const NMPlatformLnkWireGuard * lnk_wireguard, - const struct _NMPWireGuardPeer * peers, + const NMPlatformLnkWireGuard *lnk_wireguard, + const struct _NMPWireGuardPeer *peers, const NMPlatformWireGuardChangePeerFlags *peer_flags, guint peers_len, NMPlatformWireGuardChangeFlags change_flags); - gboolean (*link_vlan_change)(NMPlatform * self, + gboolean (*link_vlan_change)(NMPlatform *self, int ifindex, _NMVlanFlags flags_mask, _NMVlanFlags flags_set, @@ -1178,26 +1171,26 @@ typedef struct { gboolean egress_reset_all, const NMVlanQosMapping *egress_map, gsize n_egress_map); - gboolean (*link_tun_add)(NMPlatform * self, - const char * name, + gboolean (*link_tun_add)(NMPlatform *self, + const char *name, const NMPlatformLnkTun *props, - const NMPlatformLink ** out_link, - int * out_fd); + const NMPlatformLink **out_link, + int *out_fd); - gboolean (*infiniband_partition_add)(NMPlatform * self, + gboolean (*infiniband_partition_add)(NMPlatform *self, int parent, int p_key, const NMPlatformLink **out_link); gboolean (*infiniband_partition_delete)(NMPlatform *self, int parent, int p_key); - gboolean (*wifi_get_capabilities)(NMPlatform * self, + gboolean (*wifi_get_capabilities)(NMPlatform *self, int ifindex, _NMDeviceWifiCapabilities *caps); - gboolean (*wifi_get_station)(NMPlatform * self, + gboolean (*wifi_get_station)(NMPlatform *self, int ifindex, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate); + int *out_quality, + guint32 *out_rate); gboolean (*wifi_get_bssid)(NMPlatform *self, int ifindex, guint8 *bssid); guint32 (*wifi_get_frequency)(NMPlatform *self, int ifindex); int (*wifi_get_quality)(NMPlatform *self, int ifindex); @@ -1208,7 +1201,7 @@ typedef struct { guint32 (*wifi_find_frequency)(NMPlatform *self, int ifindex, const guint32 *freqs); void (*wifi_indicate_addressing_running)(NMPlatform *self, int ifindex, gboolean running); _NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan)(NMPlatform *self, int ifindex); - gboolean (*wifi_set_wake_on_wlan)(NMPlatform * self, + gboolean (*wifi_set_wake_on_wlan)(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl); @@ -1234,7 +1227,7 @@ typedef struct { guint32 preferred_lft, guint32 flags, const char *label); - gboolean (*ip6_address_add)(NMPlatform * self, + gboolean (*ip6_address_add)(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen, @@ -1247,22 +1240,22 @@ typedef struct { in_addr_t address, guint8 plen, in_addr_t peer_address); - gboolean (*ip6_address_delete)(NMPlatform * self, + gboolean (*ip6_address_delete)(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen); - int (*ip_route_add)(NMPlatform * self, + int (*ip_route_add)(NMPlatform *self, NMPNlmFlags flags, int addr_family, const NMPlatformIPRoute *route); - int (*ip_route_get)(NMPlatform * self, + int (*ip_route_get)(NMPlatform *self, int addr_family, gconstpointer address, int oif_ifindex, - NMPObject ** out_route); + NMPObject **out_route); - int (*routing_rule_add)(NMPlatform * self, + int (*routing_rule_add)(NMPlatform *self, NMPNlmFlags flags, const NMPlatformRoutingRule *routing_rule); @@ -1415,6 +1408,12 @@ _nm_platform_link_get_inet6_addr_gen_mode(const NMPlatformLink *pllink) return _nm_platform_uint8_inv(pllink->inet6_addr_gen_mode_inv); } +static inline gboolean +nm_platform_route_type_is_nodev(guint8 type) +{ + return NM_IN_SET(type, 6 /* RTN_BLACKHOLE */, 7 /* RTN_UNREACHABLE */, 8 /* RTN_PROHIBIT */); +} + /** * nm_platform_route_type_coerce: * @table: the route type, in its original value. @@ -1484,15 +1483,15 @@ gboolean nm_platform_sysctl_set(NMPlatform *self, int dirfd, const char *path, const char *value); -void nm_platform_sysctl_set_async(NMPlatform * self, - const char * pathid, +void nm_platform_sysctl_set_async(NMPlatform *self, + const char *pathid, int dirfd, - const char * path, - const char *const * values, + const char *path, + const char *const *values, NMPlatformAsyncCallback callback, gpointer data, - GCancellable * cancellable); -char * nm_platform_sysctl_get(NMPlatform *self, const char *pathid, int dirfd, const char *path); + GCancellable *cancellable); +char *nm_platform_sysctl_get(NMPlatform *self, const char *pathid, int dirfd, const char *path); gint32 nm_platform_sysctl_get_int32(NMPlatform *self, const char *pathid, int dirfd, @@ -1544,7 +1543,7 @@ gboolean nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(NMPlatform *self, int nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(NMPlatform *platform, const char *iface, gboolean consider_all, - gboolean * out_due_to_all); + gboolean *out_due_to_all); const char *nm_platform_if_indextoname(NMPlatform *self, int ifindex, @@ -1554,27 +1553,27 @@ int nm_platform_if_nametoindex(NMPlatform *self, const char *ifname); const NMPObject *nm_platform_link_get_obj(NMPlatform *self, int ifindex, gboolean visible_only); const NMPlatformLink *nm_platform_link_get(NMPlatform *self, int ifindex); const NMPlatformLink *nm_platform_link_get_by_ifname(NMPlatform *self, const char *ifname); -const NMPlatformLink *nm_platform_link_get_by_address(NMPlatform * self, +const NMPlatformLink *nm_platform_link_get_by_address(NMPlatform *self, NMLinkType link_type, gconstpointer address, size_t length); GPtrArray *nm_platform_link_get_all(NMPlatform *self, gboolean sort_by_name); -int nm_platform_link_add(NMPlatform * self, +int nm_platform_link_add(NMPlatform *self, NMLinkType type, - const char * name, + const char *name, int parent, - const void * address, + const void *address, size_t address_len, guint32 mtu, gconstpointer extra_data, const NMPlatformLink **out_link); static inline int -nm_platform_link_veth_add(NMPlatform * self, - const char * name, - const char * peer, +nm_platform_link_veth_add(NMPlatform *self, + const char *name, + const char *peer, const NMPlatformLink **out_link) { return nm_platform_link_add(self, NM_LINK_TYPE_VETH, name, 0, NULL, 0, 0, peer, out_link); @@ -1587,13 +1586,13 @@ nm_platform_link_dummy_add(NMPlatform *self, const char *name, const NMPlatformL } static inline int -nm_platform_link_bridge_add(NMPlatform * self, - const char * name, - const void * address, +nm_platform_link_bridge_add(NMPlatform *self, + const char *name, + const void *address, size_t address_len, guint32 mtu, const NMPlatformLnkBridge *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { return nm_platform_link_add(self, NM_LINK_TYPE_BRIDGE, @@ -1625,12 +1624,12 @@ nm_platform_link_wireguard_add(NMPlatform *self, const char *name, const NMPlatf } static inline int -nm_platform_link_gre_add(NMPlatform * self, - const char * name, - const void * address, +nm_platform_link_gre_add(NMPlatform *self, + const char *name, + const void *address, size_t address_len, const NMPlatformLnkGre *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { g_return_val_if_fail(props, -NME_BUG); @@ -1646,17 +1645,17 @@ nm_platform_link_gre_add(NMPlatform * self, } static inline int -nm_platform_link_sit_add(NMPlatform * self, - const char * name, +nm_platform_link_sit_add(NMPlatform *self, + const char *name, const NMPlatformLnkSit *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { return nm_platform_link_add(self, NM_LINK_TYPE_SIT, name, 0, NULL, 0, 0, props, out_link); } static inline int -nm_platform_link_vlan_add(NMPlatform * self, - const char * name, +nm_platform_link_vlan_add(NMPlatform *self, + const char *name, int parent, int vlanid, guint32 vlanflags, @@ -1680,26 +1679,26 @@ nm_platform_link_vlan_add(NMPlatform * self, } static inline int -nm_platform_link_vrf_add(NMPlatform * self, - const char * name, +nm_platform_link_vrf_add(NMPlatform *self, + const char *name, const NMPlatformLnkVrf *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { return nm_platform_link_add(self, NM_LINK_TYPE_VRF, name, 0, NULL, 0, 0, props, out_link); } static inline int -nm_platform_link_vxlan_add(NMPlatform * self, - const char * name, +nm_platform_link_vxlan_add(NMPlatform *self, + const char *name, const NMPlatformLnkVxlan *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { return nm_platform_link_add(self, NM_LINK_TYPE_VXLAN, name, 0, NULL, 0, 0, props, out_link); } static inline int -nm_platform_link_6lowpan_add(NMPlatform * self, - const char * name, +nm_platform_link_6lowpan_add(NMPlatform *self, + const char *name, int parent, const NMPlatformLink **out_link) { @@ -1715,10 +1714,10 @@ nm_platform_link_6lowpan_add(NMPlatform * self, } static inline int -nm_platform_link_ip6tnl_add(NMPlatform * self, - const char * name, +nm_platform_link_ip6tnl_add(NMPlatform *self, + const char *name, const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { g_return_val_if_fail(props, -NME_BUG); g_return_val_if_fail(!props->is_gre, -NME_BUG); @@ -1727,12 +1726,12 @@ nm_platform_link_ip6tnl_add(NMPlatform * self, } static inline int -nm_platform_link_ip6gre_add(NMPlatform * self, - const char * name, - const void * address, +nm_platform_link_ip6gre_add(NMPlatform *self, + const char *name, + const void *address, size_t address_len, const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { g_return_val_if_fail(props, -NME_BUG); g_return_val_if_fail(props->is_gre, -NME_BUG); @@ -1749,10 +1748,10 @@ nm_platform_link_ip6gre_add(NMPlatform * self, } static inline int -nm_platform_link_ipip_add(NMPlatform * self, - const char * name, +nm_platform_link_ipip_add(NMPlatform *self, + const char *name, const NMPlatformLnkIpIp *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { g_return_val_if_fail(props, -NME_BUG); @@ -1760,11 +1759,11 @@ nm_platform_link_ipip_add(NMPlatform * self, } static inline int -nm_platform_link_macsec_add(NMPlatform * self, - const char * name, +nm_platform_link_macsec_add(NMPlatform *self, + const char *name, int parent, const NMPlatformLnkMacsec *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { g_return_val_if_fail(props, -NME_BUG); g_return_val_if_fail(parent > 0, -NME_BUG); @@ -1781,11 +1780,11 @@ nm_platform_link_macsec_add(NMPlatform * self, } static inline int -nm_platform_link_macvlan_add(NMPlatform * self, - const char * name, +nm_platform_link_macvlan_add(NMPlatform *self, + const char *name, int parent, const NMPlatformLnkMacvlan *props, - const NMPlatformLink ** out_link) + const NMPlatformLink **out_link) { g_return_val_if_fail(props, -NME_BUG); g_return_val_if_fail(parent > 0, -NME_BUG); @@ -1807,7 +1806,7 @@ gboolean nm_platform_link_set_netns(NMPlatform *self, int ifindex, int netns_fd) struct _NMDedupMultiHeadEntry; struct _NMPLookup; -const struct _NMDedupMultiHeadEntry *nm_platform_lookup(NMPlatform * self, +const struct _NMDedupMultiHeadEntry *nm_platform_lookup(NMPlatform *self, const struct _NMPLookup *lookup); #define nm_platform_iter_obj_for_each(iter, self, lookup, obj) \ @@ -1818,7 +1817,7 @@ gboolean nm_platform_lookup_predicate_routes_main(const NMPObject *obj, gpointer gboolean nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel(const NMPObject *obj, gpointer user_data); -GPtrArray *nm_platform_lookup_clone(NMPlatform * self, +GPtrArray *nm_platform_lookup_clone(NMPlatform *self, const struct _NMPLookup *lookup, NMPObjectPredicateFunc predicate, gpointer user_data); @@ -1874,9 +1873,9 @@ nm_platform_link_change_flags(NMPlatform *self, int ifindex, unsigned value, gbo return nm_platform_link_change_flags_full(self, ifindex, value, set ? value : 0u); } -gboolean nm_platform_link_get_udev_property(NMPlatform * self, +gboolean nm_platform_link_get_udev_property(NMPlatform *self, int ifindex, - const char * name, + const char *name, const char **out_value); const char *nm_platform_link_get_udi(NMPlatform *self, int ifindex); const char *nm_platform_link_get_path(NMPlatform *self, int ifindex); @@ -1887,39 +1886,39 @@ int nm_platform_link_set_inet6_addr_gen_mode(NMPlatform *self, int ifindex, guin gboolean nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, const NMUtilsIPv6IfaceId *iid); -gboolean nm_platform_link_get_permanent_address_ethtool(NMPlatform * self, +gboolean nm_platform_link_get_permanent_address_ethtool(NMPlatform *self, int ifindex, NMPLinkAddress *out_address); -gboolean nm_platform_link_get_permanent_address(NMPlatform * self, +gboolean nm_platform_link_get_permanent_address(NMPlatform *self, const NMPlatformLink *plink, - NMPLinkAddress * out_address); + NMPLinkAddress *out_address); int nm_platform_link_set_address(NMPlatform *self, int ifindex, const void *address, size_t length); int nm_platform_link_set_mtu(NMPlatform *self, int ifindex, guint32 mtu); gboolean nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name); -void nm_platform_link_set_sriov_params_async(NMPlatform * self, +void nm_platform_link_set_sriov_params_async(NMPlatform *self, int ifindex, guint num_vfs, NMOptionBool autoprobe, NMPlatformAsyncCallback callback, gpointer callback_data, - GCancellable * cancellable); + GCancellable *cancellable); gboolean nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); -gboolean nm_platform_link_set_bridge_vlans(NMPlatform * self, +gboolean nm_platform_link_set_bridge_vlans(NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans); -char * nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex); +char *nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex); guint nm_platform_link_get_dev_id(NMPlatform *self, int ifindex); gboolean nm_platform_link_get_wake_on_lan(NMPlatform *self, int ifindex); gboolean nm_platform_link_get_driver_info(NMPlatform *self, int ifindex, - char ** out_driver_name, - char ** out_driver_version, - char ** out_fw_version); + char **out_driver_name, + char **out_driver_version, + char **out_fw_version); gboolean nm_platform_link_supports_carrier_detect(NMPlatform *self, int ifindex); gboolean nm_platform_link_supports_vlans(NMPlatform *self, int ifindex); @@ -1932,14 +1931,14 @@ gboolean nm_platform_sysctl_master_set_option(NMPlatform *self, int ifindex, const char *option, const char *value); -char * nm_platform_sysctl_master_get_option(NMPlatform *self, int ifindex, const char *option); +char *nm_platform_sysctl_master_get_option(NMPlatform *self, int ifindex, const char *option); gboolean nm_platform_sysctl_slave_set_option(NMPlatform *self, int ifindex, const char *option, const char *value); -char * nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *option); +char *nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *option); -const NMPObject *nm_platform_link_get_lnk(NMPlatform * self, +const NMPObject *nm_platform_link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link); @@ -1982,7 +1981,7 @@ nm_platform_link_get_lnk_wireguard(NMPlatform *self, int ifindex, const NMPlatfo gboolean nm_platform_link_vlan_set_ingress_map(NMPlatform *self, int ifindex, int from, int to); gboolean nm_platform_link_vlan_set_egress_map(NMPlatform *self, int ifindex, int from, int to); -gboolean nm_platform_link_vlan_change(NMPlatform * self, +gboolean nm_platform_link_vlan_change(NMPlatform *self, int ifindex, _NMVlanFlags flags_mask, _NMVlanFlags flags_set, @@ -1993,30 +1992,30 @@ gboolean nm_platform_link_vlan_change(NMPlatform * self, const NMVlanQosMapping *egress_map, gsize n_egress_map); -int nm_platform_link_infiniband_add(NMPlatform * self, +int nm_platform_link_infiniband_add(NMPlatform *self, int parent, int p_key, const NMPlatformLink **out_link); int nm_platform_link_infiniband_delete(NMPlatform *self, int parent, int p_key); -gboolean nm_platform_link_infiniband_get_properties(NMPlatform * self, +gboolean nm_platform_link_infiniband_get_properties(NMPlatform *self, int ifindex, - int * parent, - int * p_key, + int *parent, + int *p_key, const char **mode); gboolean nm_platform_link_veth_get_properties(NMPlatform *self, int ifindex, int *out_peer_ifindex); -gboolean nm_platform_link_tun_get_properties(NMPlatform * self, +gboolean nm_platform_link_tun_get_properties(NMPlatform *self, int ifindex, NMPlatformLnkTun *out_properties); gboolean nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, _NMDeviceWifiCapabilities *caps); guint32 nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex); -gboolean nm_platform_wifi_get_station(NMPlatform * self, +gboolean nm_platform_wifi_get_station(NMPlatform *self, int ifindex, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate); + int *out_quality, + guint32 *out_rate); _NM80211Mode nm_platform_wifi_get_mode(NMPlatform *self, int ifindex); void nm_platform_wifi_set_mode(NMPlatform *self, int ifindex, _NM80211Mode mode); void nm_platform_wifi_set_powersave(NMPlatform *self, int ifindex, guint32 powersave); @@ -2045,24 +2044,24 @@ const NMPlatformIP4Address *nm_platform_ip4_address_get(NMPlatform *self, guint8 plen, in_addr_t peer_address); -int nm_platform_link_sit_add(NMPlatform * self, - const char * name, +int nm_platform_link_sit_add(NMPlatform *self, + const char *name, const NMPlatformLnkSit *props, - const NMPlatformLink ** out_link); -int nm_platform_link_tun_add(NMPlatform * self, - const char * name, + const NMPlatformLink **out_link); +int nm_platform_link_tun_add(NMPlatform *self, + const char *name, const NMPlatformLnkTun *props, - const NMPlatformLink ** out_link, - int * out_fd); + const NMPlatformLink **out_link, + int *out_fd); gboolean nm_platform_link_6lowpan_get_properties(NMPlatform *self, int ifindex, int *out_parent); int nm_platform_link_wireguard_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link); -int nm_platform_link_wireguard_change(NMPlatform * self, +int nm_platform_link_wireguard_change(NMPlatform *self, int ifindex, - const NMPlatformLnkWireGuard * lnk_wireguard, - const struct _NMPWireGuardPeer * peers, + const NMPlatformLnkWireGuard *lnk_wireguard, + const struct _NMPWireGuardPeer *peers, const NMPlatformWireGuardChangePeerFlags *peer_flags, guint peers_len, NMPlatformWireGuardChangeFlags change_flags); @@ -2082,7 +2081,7 @@ gboolean nm_platform_ip4_address_add(NMPlatform *self, guint32 preferred_lft, guint32 flags, const char *label); -gboolean nm_platform_ip6_address_add(NMPlatform * self, +gboolean nm_platform_ip6_address_add(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen, @@ -2101,8 +2100,8 @@ nm_platform_ip6_address_delete(NMPlatform *self, int ifindex, struct in6_addr ad gboolean nm_platform_ip_address_sync(NMPlatform *self, int addr_family, int ifindex, - GPtrArray * known_addresses, - GPtrArray * addresses_prune); + GPtrArray *known_addresses, + GPtrArray *addresses_prune); GPtrArray *nm_platform_ip_address_get_prune_list(NMPlatform *self, int addr_family, @@ -2113,7 +2112,7 @@ static inline gboolean _nm_platform_ip_address_sync(NMPlatform *self, int addr_family, int ifindex, - GPtrArray * known_addresses, + GPtrArray *known_addresses, gboolean full_sync) { gs_unref_ptrarray GPtrArray *addresses_prune = NULL; @@ -2135,7 +2134,7 @@ nm_platform_ip4_address_sync(NMPlatform *self, int ifindex, GPtrArray *known_add static inline gboolean nm_platform_ip6_address_sync(NMPlatform *self, int ifindex, - GPtrArray * known_addresses, + GPtrArray *known_addresses, gboolean full_sync) { return _nm_platform_ip_address_sync(self, AF_INET6, ifindex, known_addresses, full_sync); @@ -2188,7 +2187,9 @@ static inline gconstpointer nm_platform_ip_route_get_gateway(int addr_family, const NMPlatformIPRoute *route) { nm_assert_addr_family(addr_family); - nm_assert(route); + + if (!route) + return NULL; if (NM_IS_IPv4(addr_family)) return &((NMPlatformIP4Route *) route)->gateway; @@ -2199,7 +2200,7 @@ int nm_platform_ip_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPObjec int nm_platform_ip4_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route); int nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route); -GPtrArray *nm_platform_ip_route_get_prune_list(NMPlatform * self, +GPtrArray *nm_platform_ip_route_get_prune_list(NMPlatform *self, int addr_family, int ifindex, NMIPRouteTableSyncMode route_table_sync); @@ -2207,19 +2208,19 @@ GPtrArray *nm_platform_ip_route_get_prune_list(NMPlatform * self, gboolean nm_platform_ip_route_sync(NMPlatform *self, int addr_family, int ifindex, - GPtrArray * routes, - GPtrArray * routes_prune, + GPtrArray *routes, + GPtrArray *routes_prune, GPtrArray **out_temporary_not_available); gboolean nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex); -int nm_platform_ip_route_get(NMPlatform * self, +int nm_platform_ip_route_get(NMPlatform *self, int addr_family, gconstpointer address, int oif_ifindex, - NMPObject ** out_route); + NMPObject **out_route); -int nm_platform_routing_rule_add(NMPlatform * self, +int nm_platform_routing_rule_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformRoutingRule *routing_rule); @@ -2229,8 +2230,8 @@ int nm_platform_tfilter_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatfor int nm_platform_tfilter_delete(NMPlatform *self, int ifindex, guint32 parent, gboolean log_error); gboolean nm_platform_tc_sync(NMPlatform *self, int ifindex, - GPtrArray * known_qdiscs, - GPtrArray * known_tfilters); + GPtrArray *known_qdiscs, + GPtrArray *known_tfilters); const char *nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len); const char *nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len); @@ -2263,10 +2264,10 @@ const char *nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize le const char * nm_platform_bridge_vlan_to_string(const NMPlatformBridgeVlan *vlan, char *buf, gsize len); -const char *nm_platform_vlan_qos_mapping_to_string(const char * name, +const char *nm_platform_vlan_qos_mapping_to_string(const char *name, const NMVlanQosMapping *map, gsize n_map, - char * buf, + char *buf, gsize len); const char * @@ -2339,13 +2340,13 @@ void nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHash void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h); void nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, - NMHashState * h); + NMHashState *h); void nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, - NMHashState * h); + NMHashState *h); void nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj, NMPlatformRoutingRuleCmpType cmp_type, - NMHashState * h); + NMHashState *h); void nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h); void nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h); void nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h); @@ -2372,34 +2373,34 @@ const char *nm_platform_route_scope2str(int scope, char *buf, gsize len); int nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatformIPAddress *b); -gboolean nm_platform_ethtool_set_wake_on_lan(NMPlatform * self, +gboolean nm_platform_ethtool_set_wake_on_lan(NMPlatform *self, int ifindex, _NMSettingWiredWakeOnLan wol, - const char * wol_password); -gboolean nm_platform_ethtool_set_link_settings(NMPlatform * self, + const char *wol_password); +gboolean nm_platform_ethtool_set_link_settings(NMPlatform *self, int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); -gboolean nm_platform_ethtool_get_link_settings(NMPlatform * self, +gboolean nm_platform_ethtool_get_link_settings(NMPlatform *self, int ifindex, - gboolean * out_autoneg, - guint32 * out_speed, + gboolean *out_autoneg, + guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); NMEthtoolFeatureStates *nm_platform_ethtool_get_link_features(NMPlatform *self, int ifindex); gboolean nm_platform_ethtool_set_features( - NMPlatform * self, + NMPlatform *self, int ifindex, const NMEthtoolFeatureStates *features, const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, gboolean do_set /* or reset */); -gboolean nm_platform_ethtool_get_link_coalesce(NMPlatform * self, +gboolean nm_platform_ethtool_get_link_coalesce(NMPlatform *self, int ifindex, NMEthtoolCoalesceState *coalesce); -gboolean nm_platform_ethtool_set_coalesce(NMPlatform * self, +gboolean nm_platform_ethtool_set_coalesce(NMPlatform *self, int ifindex, const NMEthtoolCoalesceState *coalesce); @@ -2416,7 +2417,7 @@ nm_platform_ethtool_set_pause(NMPlatform *self, int ifindex, const NMEthtoolPaus void nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self, int ifindex, - GPtrArray * ip4_dev_route_blacklist); + GPtrArray *ip4_dev_route_blacklist); struct _NMDedupMultiIndex *nm_platform_get_multi_idx(NMPlatform *self); @@ -2426,6 +2427,7 @@ NMPlatformIP4Route *nm_platform_ip4_address_generate_device_route(const NMPlatfo int ifindex, guint32 route_table, guint32 route_metric, + gboolean force_commit, NMPlatformIP4Route *dst); /*****************************************************************************/ diff --git a/src/libnm-platform/nmp-netns.c b/src/libnm-platform/nmp-netns.c index d06c3e11..2563e8f6 100644 --- a/src/libnm-platform/nmp-netns.c +++ b/src/libnm-platform/nmp-netns.c @@ -147,8 +147,8 @@ static GArray * _netns_stack_get_impl(void) { gs_unref_object NMPNetns *netns = NULL; - gs_free_error GError *error = NULL; - GArray * s; + gs_free_error GError *error = NULL; + GArray *s; s = g_array_new(FALSE, FALSE, sizeof(NetnsInfo)); g_array_set_clear_func(s, _netns_stack_clear_cb); @@ -444,7 +444,7 @@ nmp_netns_get_fd_mnt(NMPNetns *self) static gboolean _nmp_netns_push_type(NMPNetns *self, int ns_types) { - GArray * netns_stack = _netns_stack_get(); + GArray *netns_stack = _netns_stack_get(); NetnsInfo *info; char sbuf[100]; @@ -493,10 +493,10 @@ nmp_netns_push_type(NMPNetns *self, int ns_types) NMPNetns * nmp_netns_new(void) { - GArray * netns_stack = _netns_stack_get(); - NMPNetns * self; + GArray *netns_stack = _netns_stack_get(); + NMPNetns *self; int errsv; - GError * error = NULL; + GError *error = NULL; unsigned long mountflags = 0; if (!_stack_peek(netns_stack)) { @@ -553,7 +553,7 @@ err_out: gboolean nmp_netns_pop(NMPNetns *self) { - GArray * netns_stack = _netns_stack_get(); + GArray *netns_stack = _netns_stack_get(); NetnsInfo *info; int ns_types; @@ -608,9 +608,9 @@ nmp_netns_is_initial(void) gboolean nmp_netns_bind_to_path(NMPNetns *self, const char *filename, int *out_fd) { - gs_free char * dirname = NULL; - int errsv; - int fd; + gs_free char *dirname = NULL; + int errsv; + int fd; nm_auto_pop_netns NMPNetns *netns_pop = NULL; g_return_val_if_fail(NMP_IS_NETNS(self), FALSE); @@ -690,7 +690,7 @@ nmp_netns_bind_to_path_destroy(NMPNetns *self, const char *filename) static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMPNetns * self = NMP_NETNS(object); + NMPNetns *self = NMP_NETNS(object); NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self); switch (prop_id) { @@ -717,7 +717,7 @@ nmp_netns_init(NMPNetns *self) static void dispose(GObject *object) { - NMPNetns * self = NMP_NETNS(object); + NMPNetns *self = NMP_NETNS(object); NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self); nm_close(priv->fd_net); diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index 559fd8d6..d518e6e5 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -279,8 +279,8 @@ static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class; static void _idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj * obj, - NMHashState * h) + const NMDedupMultiObj *obj, + NMHashState *h) { const NMPObject *o = (NMPObject *) obj; @@ -292,8 +292,8 @@ _idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type, static gboolean _idx_obj_id_equal(const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj * obj_a, - const NMDedupMultiObj * obj_b) + const NMDedupMultiObj *obj_a, + const NMDedupMultiObj *obj_b) { const NMPObject *o_a = (NMPObject *) obj_a; const NMPObject *o_b = (NMPObject *) obj_b; @@ -307,9 +307,9 @@ _idx_obj_id_equal(const NMDedupMultiIdxType *idx_type, static guint _idx_obj_part(const DedupMultiIdxType *idx_type, - const NMPObject * obj_a, - const NMPObject * obj_b, - NMHashState * h) + const NMPObject *obj_a, + const NMPObject *obj_b, + NMHashState *h) { NMPObjectType obj_type; @@ -386,7 +386,11 @@ _idx_obj_part(const DedupMultiIdxType *idx_type, nm_hash_update_val(h, obj_a); return 0; } - nm_assert(NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex > 0); + nm_assert(NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex > 0 + || (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex == 0 + && NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_a), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE))); if (obj_b) { return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b) && NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex @@ -401,14 +405,14 @@ _idx_obj_part(const DedupMultiIdxType *idx_type, case NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID: obj_type = NMP_OBJECT_GET_TYPE(obj_a); if (!NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) - || NMP_OBJECT_CAST_IP_ROUTE(obj_a)->ifindex <= 0) { + || NMP_OBJECT_CAST_IP_ROUTE(obj_a)->ifindex < 0) { if (h) nm_hash_update_val(h, obj_a); return 0; } if (obj_b) { return obj_type == NMP_OBJECT_GET_TYPE(obj_b) - && NMP_OBJECT_CAST_IP_ROUTE(obj_b)->ifindex > 0 + && NMP_OBJECT_CAST_IP_ROUTE(obj_b)->ifindex >= 0 && (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE ? (nm_platform_ip4_route_cmp(&obj_a->ip4_route, &obj_b->ip4_route, @@ -466,16 +470,16 @@ _idx_obj_partitionable(const NMDedupMultiIdxType *idx_type, const NMDedupMultiOb static void _idx_obj_partition_hash_update(const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj * obj, - NMHashState * h) + const NMDedupMultiObj *obj, + NMHashState *h) { _idx_obj_part((DedupMultiIdxType *) idx_type, (NMPObject *) obj, NULL, h); } static gboolean _idx_obj_partition_equal(const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj * obj_a, - const NMDedupMultiObj * obj_b) + const NMDedupMultiObj *obj_a, + const NMDedupMultiObj *obj_b) { return _idx_obj_part((DedupMultiIdxType *) idx_type, (NMPObject *) obj_a, @@ -528,8 +532,8 @@ _vlan_xgress_qos_mappings_cmp(guint n_map, } static void -_vlan_xgress_qos_mappings_cpy(guint * dst_n_map, - NMVlanQosMapping ** dst_map, +_vlan_xgress_qos_mappings_cpy(guint *dst_n_map, + NMVlanQosMapping **dst_map, guint src_n_map, const NMVlanQosMapping *src_map) { @@ -655,7 +659,7 @@ _nmp_object_fixup_link_udev_fields(NMPObject **obj_new, NMPObject *obj_orig, gbo { const char *driver = NULL; gboolean initialized = FALSE; - NMPObject * obj; + NMPObject *obj; nm_assert(obj_orig || *obj_new); nm_assert(obj_new); @@ -695,8 +699,8 @@ _nmp_object_fixup_link_udev_fields(NMPObject **obj_new, NMPObject *obj_orig, gbo } static void -_nmp_object_fixup_link_master_connected(NMPObject ** obj_new, - NMPObject * obj_orig, +_nmp_object_fixup_link_master_connected(NMPObject **obj_new, + NMPObject *obj_orig, const NMPCache *cache) { NMPObject *obj; @@ -775,7 +779,7 @@ NMPObject * nmp_object_new(NMPObjectType obj_type, gconstpointer plobj) { const NMPClass *klass = nmp_class_from_type(obj_type); - NMPObject * obj; + NMPObject *obj; obj = _nmp_object_new_from_class(klass); if (plobj) @@ -891,9 +895,9 @@ nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in /*****************************************************************************/ const char * -nmp_object_to_string(const NMPObject * obj, +nmp_object_to_string(const NMPObject *obj, NMPObjectToStringMode to_string_mode, - char * buf, + char *buf, gsize buf_size) { const NMPClass *klass; @@ -937,13 +941,13 @@ nmp_object_to_string(const NMPObject * obj, } static const char * -_vt_cmd_obj_to_string_link(const NMPObject * obj, +_vt_cmd_obj_to_string_link(const NMPObject *obj, NMPObjectToStringMode to_string_mode, - char * buf, + char *buf, gsize buf_size) { const NMPClass *klass = NMP_OBJECT_GET_CLASS(obj); - char * b = buf; + char *b = buf; switch (to_string_mode) { case NMP_OBJECT_TO_STRING_ID: @@ -982,14 +986,14 @@ _vt_cmd_obj_to_string_link(const NMPObject * obj, } static const char * -_vt_cmd_obj_to_string_lnk_vlan(const NMPObject * obj, +_vt_cmd_obj_to_string_lnk_vlan(const NMPObject *obj, NMPObjectToStringMode to_string_mode, - char * buf, + char *buf, gsize buf_size) { const NMPClass *klass; char buf2[sizeof(_nm_utils_to_string_buffer)]; - char * b; + char *b; gsize l; klass = NMP_OBJECT_GET_CLASS(obj); @@ -1046,14 +1050,14 @@ _vt_cmd_obj_to_string_lnk_vlan(const NMPObject * obj, } static const char * -_vt_cmd_obj_to_string_lnk_wireguard(const NMPObject * obj, +_vt_cmd_obj_to_string_lnk_wireguard(const NMPObject *obj, NMPObjectToStringMode to_string_mode, - char * buf, + char *buf, gsize buf_size) { const NMPClass *klass; char buf2[sizeof(_nm_utils_to_string_buffer)]; - char * b; + char *b; guint i; klass = NMP_OBJECT_GET_CLASS(obj); @@ -1100,7 +1104,7 @@ _vt_cmd_obj_to_string_lnk_wireguard(const NMPObject * obj, #define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \ static const char *_vt_cmd_plobj_to_string_id_##type(const NMPlatformObject *_obj, \ - char * buf, \ + char *buf, \ gsize buf_len) \ { \ plat_type *const obj = (plat_type *) _obj; \ @@ -1740,8 +1744,7 @@ _vt_cmd_obj_is_alive_ipx_route(const NMPObject *obj) * Instead we create a dead object, and nmp_cache_update_netlink() * will remove the old version of the update. **/ - return NMP_OBJECT_CAST_IP_ROUTE(obj)->ifindex > 0 - && !NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, RTM_F_CLONED); + return !NM_FLAGS_HAS(NMP_OBJECT_CAST_IP_ROUTE(obj)->r_rtm_flags, RTM_F_CLONED); } static gboolean @@ -1825,7 +1828,7 @@ static const guint8 _supported_cache_ids_routing_rules[] = { static void _vt_dedup_obj_destroy(NMDedupMultiObj *obj) { - NMPObject * o = (NMPObject *) obj; + NMPObject *o = (NMPObject *) obj; const NMPClass *klass; nm_assert(o->parent._ref_count == 0); @@ -1907,7 +1910,7 @@ nmp_cache_link_connected_for_slave(int ifindex_master, const NMPObject *slave) * Returns: %TRUE, if @master->link.connected should be flipped/toggled. **/ gboolean -nmp_cache_link_connected_needs_toggle(const NMPCache * cache, +nmp_cache_link_connected_needs_toggle(const NMPCache *cache, const NMPObject *master, const NMPObject *potential_slave, const NMPObject *ignore_slave) @@ -1972,7 +1975,7 @@ nmp_cache_link_connected_needs_toggle(const NMPCache * cache, * The connected flag of that master should be toggled. */ const NMPObject * -nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, +nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache *cache, int master_ifindex, const NMPObject *potential_slave, const NMPObject *ignore_slave) @@ -1990,7 +1993,7 @@ nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, /*****************************************************************************/ static const NMDedupMultiEntry * -_lookup_entry_with_idx_type(const NMPCache * cache, +_lookup_entry_with_idx_type(const NMPCache *cache, NMPCacheIdType cache_id_type, const NMPObject *obj) { @@ -2014,7 +2017,7 @@ _lookup_entry(const NMPCache *cache, const NMPObject *obj) } const NMDedupMultiEntry * -nmp_cache_lookup_entry_with_idx_type(const NMPCache * cache, +nmp_cache_lookup_entry_with_idx_type(const NMPCache *cache, NMPCacheIdType cache_id_type, const NMPObject *obj) { @@ -2063,7 +2066,7 @@ nmp_cache_lookup_link(const NMPCache *cache, int ifindex) /*****************************************************************************/ const NMDedupMultiHeadEntry * -nmp_cache_lookup_all(const NMPCache * cache, +nmp_cache_lookup_all(const NMPCache *cache, NMPCacheIdType cache_id_type, const NMPObject *select_obj) { @@ -2143,7 +2146,15 @@ nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex) NMP_OBJECT_TYPE_QDISC, NMP_OBJECT_TYPE_TFILTER)); - if (ifindex <= 0) { + if (G_UNLIKELY( + (ifindex < 0) + || (ifindex == 0 + && !NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)))) { + /* This function used to have a fallback that meant to lookup all objects, if + * ifindex is non-positive. As routes can have a zero ifindex, that fallback is + * confusing and no longer supported. Only have this code, to catch accidental bugs + * after the API change. */ + nm_assert_not_reached(); return nmp_lookup_init_obj_type(lookup, obj_type); } @@ -2220,7 +2231,7 @@ nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup, } const NMPLookup * -nmp_lookup_init_ip6_route_by_weak_id(NMPLookup * lookup, +nmp_lookup_init_ip6_route_by_weak_id(NMPLookup *lookup, const struct in6_addr *network, guint plen, guint32 metric, @@ -2269,10 +2280,10 @@ nmp_cache_lookup_to_array(const NMDedupMultiHeadEntry *head_entry, NMPObjectType obj_type, gboolean visible_only) { - const NMPClass * klass = nmp_class_from_type(obj_type); + const NMPClass *klass = nmp_class_from_type(obj_type); NMDedupMultiIter iter; const NMPObject *o; - GArray * array; + GArray *array; g_return_val_if_fail(klass, NULL); @@ -2289,19 +2300,19 @@ nmp_cache_lookup_to_array(const NMDedupMultiHeadEntry *head_entry, /*****************************************************************************/ const NMPObject * -nmp_cache_lookup_link_full(const NMPCache * cache, +nmp_cache_lookup_link_full(const NMPCache *cache, int ifindex, - const char * ifname, + const char *ifname, gboolean visible_only, NMLinkType link_type, NMPObjectMatchFn match_fn, gpointer user_data) { NMPObject obj_needle; - const NMPObject * obj; + const NMPObject *obj; NMDedupMultiIter iter; const NMDedupMultiHeadEntry *head_entry; - const NMPlatformLink * link = NULL; + const NMPlatformLink *link = NULL; NMPLookup lookup; if (ifindex > 0) { @@ -2369,8 +2380,8 @@ _obj_get_add_mode(const NMPObject *obj) static void _idxcache_update_order_for_dump(NMPCache *cache, const NMDedupMultiEntry *entry) { - const NMPClass * klass; - const guint8 * i_idx_type; + const NMPClass *klass; + const guint8 *i_idx_type; const NMDedupMultiEntry *entry2; nm_dedup_multi_entry_reorder(entry, NULL, TRUE); @@ -2396,7 +2407,7 @@ _idxcache_update_order_for_dump(NMPCache *cache, const NMDedupMultiEntry *entry) } static void -_idxcache_update_other_cache_ids(NMPCache * cache, +_idxcache_update_other_cache_ids(NMPCache *cache, NMPCacheIdType cache_id_type, const NMPObject *obj_old, const NMPObject *obj_new, @@ -2405,7 +2416,7 @@ _idxcache_update_other_cache_ids(NMPCache * cache, const NMDedupMultiEntry *entry_new; const NMDedupMultiEntry *entry_old; const NMDedupMultiEntry *entry_order; - NMDedupMultiIdxType * idx_type; + NMDedupMultiIdxType *idx_type; nm_assert(obj_new || obj_old); nm_assert(!obj_new || NMP_OBJECT_GET_TYPE(obj_new) != NMP_OBJECT_TYPE_UNKNOWN); @@ -2474,15 +2485,15 @@ _idxcache_update_other_cache_ids(NMPCache * cache, } static void -_idxcache_update(NMPCache * cache, - const NMDedupMultiEntry * entry_old, - NMPObject * obj_new, +_idxcache_update(NMPCache *cache, + const NMDedupMultiEntry *entry_old, + NMPObject *obj_new, gboolean is_dump, const NMDedupMultiEntry **out_entry_new) { - const NMPClass * klass; - const guint8 * i_idx_type; - NMDedupMultiIdxType * idx_type_o = _idx_type_get(cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE); + const NMPClass *klass; + const guint8 *i_idx_type; + NMDedupMultiIdxType *idx_type_o = _idx_type_get(cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE); const NMDedupMultiEntry *entry_new = NULL; nm_auto_nmpobj const NMPObject *obj_old = NULL; @@ -2559,14 +2570,14 @@ _idxcache_update(NMPCache * cache, } NMPCacheOpsType -nmp_cache_remove(NMPCache * cache, - const NMPObject * obj_needle, +nmp_cache_remove(NMPCache *cache, + const NMPObject *obj_needle, gboolean equals_by_ptr, gboolean only_dirty, const NMPObject **out_obj_old) { const NMDedupMultiEntry *entry_old; - const NMPObject * obj_old; + const NMPObject *obj_old; entry_old = _lookup_entry(cache, obj_needle); @@ -2593,14 +2604,14 @@ nmp_cache_remove(NMPCache * cache, } NMPCacheOpsType -nmp_cache_remove_netlink(NMPCache * cache, - const NMPObject * obj_needle, +nmp_cache_remove_netlink(NMPCache *cache, + const NMPObject *obj_needle, const NMPObject **out_obj_old, const NMPObject **out_obj_new) { - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new = NULL; - const NMPObject * obj_old; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new = NULL; + const NMPObject *obj_old; nm_auto_nmpobj NMPObject *obj_new = NULL; entry_old = _lookup_entry(cache, obj_needle); @@ -2679,15 +2690,15 @@ nmp_cache_remove_netlink(NMPCache * cache, * and @out_obj_new will be set accordingly. **/ NMPCacheOpsType -nmp_cache_update_netlink(NMPCache * cache, - NMPObject * obj_hand_over, +nmp_cache_update_netlink(NMPCache *cache, + NMPObject *obj_hand_over, gboolean is_dump, const NMPObject **out_obj_old, const NMPObject **out_obj_new) { const NMDedupMultiEntry *entry_old; const NMDedupMultiEntry *entry_new; - const NMPObject * obj_old; + const NMPObject *obj_old; gboolean is_alive; nm_assert(cache); @@ -2789,20 +2800,20 @@ nmp_cache_update_netlink(NMPCache * cache, } NMPCacheOpsType -nmp_cache_update_netlink_route(NMPCache * cache, - NMPObject * obj_hand_over, +nmp_cache_update_netlink_route(NMPCache *cache, + NMPObject *obj_hand_over, gboolean is_dump, guint16 nlmsgflags, const NMPObject **out_obj_old, const NMPObject **out_obj_new, const NMPObject **out_obj_replace, - gboolean * out_resync_required) + gboolean *out_resync_required) { NMDedupMultiIter iter; - const NMDedupMultiEntry * entry_old; - const NMDedupMultiEntry * entry_new; - const NMDedupMultiEntry * entry_cur; - const NMDedupMultiEntry * entry_replace; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new; + const NMDedupMultiEntry *entry_cur; + const NMDedupMultiEntry *entry_replace; const NMDedupMultiHeadEntry *head_entry; gboolean is_alive; NMPCacheOpsType ops_type = NMP_CACHE_OPS_UNCHANGED; @@ -2937,16 +2948,16 @@ out: } NMPCacheOpsType -nmp_cache_update_link_udev(NMPCache * cache, +nmp_cache_update_link_udev(NMPCache *cache, int ifindex, struct udev_device *udevice, - const NMPObject ** out_obj_old, - const NMPObject ** out_obj_new) + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) { - const NMPObject *obj_old; + const NMPObject *obj_old; nm_auto_nmpobj NMPObject *obj_new = NULL; - const NMDedupMultiEntry * entry_old; - const NMDedupMultiEntry * entry_new; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new; entry_old = nmp_cache_lookup_entry_link(cache, ifindex); @@ -2997,14 +3008,14 @@ nmp_cache_update_link_udev(NMPCache * cache, } NMPCacheOpsType -nmp_cache_update_link_master_connected(NMPCache * cache, +nmp_cache_update_link_master_connected(NMPCache *cache, int ifindex, const NMPObject **out_obj_old, const NMPObject **out_obj_new) { - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new = NULL; - const NMPObject * obj_old; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new = NULL; + const NMPObject *obj_old; nm_auto_nmpobj NMPObject *obj_new = NULL; entry_old = nmp_cache_lookup_entry_link(cache, ifindex); diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h index bf140d78..784dcc2d 100644 --- a/src/libnm-platform/nmp-object.h +++ b/src/libnm-platform/nmp-object.h @@ -170,9 +170,9 @@ typedef enum { typedef struct { NMDedupMultiObjClass parent; - const char * obj_type_name; - const char * signal_type; - const guint8 * supported_cache_ids; + const char *obj_type_name; + const char *signal_type; + const guint8 *supported_cache_ids; int sizeof_data; int sizeof_public; int addr_family; @@ -189,9 +189,9 @@ typedef struct { void (*cmd_obj_dispose)(NMPObject *obj); gboolean (*cmd_obj_is_alive)(const NMPObject *obj); gboolean (*cmd_obj_is_visible)(const NMPObject *obj); - const char *(*cmd_obj_to_string)(const NMPObject * obj, + const char *(*cmd_obj_to_string)(const NMPObject *obj, NMPObjectToStringMode to_string_mode, - char * buf, + char *buf, gsize buf_size); /* functions that operate on NMPlatformObject */ @@ -302,7 +302,7 @@ typedef struct { typedef struct { NMPlatformLnkWireGuard _public; - const NMPWireGuardPeer * peers; + const NMPWireGuardPeer *peers; const NMPWireGuardAllowedIP *_allowed_ips_buf; guint peers_len; guint _allowed_ips_buf_len; @@ -662,7 +662,7 @@ nmp_object_ref_set_up_cast(gpointer pp, gconstpointer obj) { gboolean _changed = FALSE; const NMPObject *p; - gconstpointer * pp2 = pp; + gconstpointer *pp2 = pp; nm_assert(!pp2 || !*pp2 || NMP_OBJECT_IS_VALID(NMP_OBJECT_UP_CAST(*pp2))); nm_assert(!obj || NMP_OBJECT_IS_VALID(NMP_OBJECT_UP_CAST(obj))); @@ -699,9 +699,9 @@ const NMPObject *nmp_object_stackinit_id_ip4_address(NMPObject *obj, const NMPObject * nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in6_addr *address); -const char *nmp_object_to_string(const NMPObject * obj, +const char *nmp_object_to_string(const NMPObject *obj, NMPObjectToStringMode to_string_mode, - char * buf, + char *buf, gsize buf_size); void nmp_object_hash_update(const NMPObject *obj, NMHashState *h); @@ -758,7 +758,7 @@ _nm_auto_nmpobj_cleanup(gpointer p) typedef struct _NMPCache NMPCache; -typedef void (*NMPCachePreHook)(NMPCache * cache, +typedef void (*NMPCachePreHook)(NMPCache *cache, const NMPObject *old, const NMPObject *new, NMPCacheOpsType ops_type, @@ -766,12 +766,12 @@ typedef void (*NMPCachePreHook)(NMPCache * cache, typedef gboolean (*NMPObjectMatchFn)(const NMPObject *obj, gpointer user_data); const NMDedupMultiEntry *nmp_cache_lookup_entry(const NMPCache *cache, const NMPObject *obj); -const NMDedupMultiEntry *nmp_cache_lookup_entry_with_idx_type(const NMPCache * cache, +const NMDedupMultiEntry *nmp_cache_lookup_entry_with_idx_type(const NMPCache *cache, NMPCacheIdType cache_id_type, const NMPObject *obj); const NMDedupMultiEntry *nmp_cache_lookup_entry_link(const NMPCache *cache, int ifindex); -const NMPObject * nmp_cache_lookup_obj(const NMPCache *cache, const NMPObject *obj); -const NMPObject * nmp_cache_lookup_link(const NMPCache *cache, int ifindex); +const NMPObject *nmp_cache_lookup_obj(const NMPCache *cache, const NMPObject *obj); +const NMPObject *nmp_cache_lookup_link(const NMPCache *cache, int ifindex); typedef struct _NMPLookup NMPLookup; @@ -780,7 +780,7 @@ struct _NMPLookup { NMPObject selector_obj; }; -const NMDedupMultiHeadEntry *nmp_cache_lookup_all(const NMPCache * cache, +const NMDedupMultiHeadEntry *nmp_cache_lookup_all(const NMPCache *cache, NMPCacheIdType cache_id_type, const NMPObject *select_obj); @@ -800,7 +800,7 @@ const NMPLookup *nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup, guint plen, guint32 metric, guint8 tos); -const NMPLookup *nmp_lookup_init_ip6_route_by_weak_id(NMPLookup * lookup, +const NMPLookup *nmp_lookup_init_ip6_route_by_weak_id(NMPLookup *lookup, const struct in6_addr *network, guint plen, guint32 metric, @@ -858,20 +858,20 @@ nmp_cache_iter_next_link(NMDedupMultiIter *iter, const NMPlatformLink **out_obj) #define nmp_cache_iter_for_each_link(iter, head, obj) \ for (nm_dedup_multi_iter_init((iter), (head)); nmp_cache_iter_next_link((iter), (obj));) -const NMPObject *nmp_cache_lookup_link_full(const NMPCache * cache, +const NMPObject *nmp_cache_lookup_link_full(const NMPCache *cache, int ifindex, - const char * ifname, + const char *ifname, gboolean visible_only, NMLinkType link_type, NMPObjectMatchFn match_fn, gpointer user_data); gboolean nmp_cache_link_connected_for_slave(int ifindex_master, const NMPObject *slave); -gboolean nmp_cache_link_connected_needs_toggle(const NMPCache * cache, +gboolean nmp_cache_link_connected_needs_toggle(const NMPCache *cache, const NMPObject *master, const NMPObject *potential_slave, const NMPObject *ignore_slave); -const NMPObject *nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, +const NMPObject *nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache *cache, int master_ifindex, const NMPObject *potential_slave, const NMPObject *ignore_slave); @@ -880,42 +880,42 @@ gboolean nmp_cache_use_udev_get(const NMPCache *cache); void nmtst_assert_nmp_cache_is_consistent(const NMPCache *cache); -NMPCacheOpsType nmp_cache_remove(NMPCache * cache, - const NMPObject * obj_needle, +NMPCacheOpsType nmp_cache_remove(NMPCache *cache, + const NMPObject *obj_needle, gboolean equals_by_ptr, gboolean only_dirty, const NMPObject **out_obj_old); -NMPCacheOpsType nmp_cache_remove_netlink(NMPCache * cache, - const NMPObject * obj_needle, +NMPCacheOpsType nmp_cache_remove_netlink(NMPCache *cache, + const NMPObject *obj_needle, const NMPObject **out_obj_old, const NMPObject **out_obj_new); -NMPCacheOpsType nmp_cache_update_netlink(NMPCache * cache, - NMPObject * obj_hand_over, +NMPCacheOpsType nmp_cache_update_netlink(NMPCache *cache, + NMPObject *obj_hand_over, gboolean is_dump, const NMPObject **out_obj_old, const NMPObject **out_obj_new); -NMPCacheOpsType nmp_cache_update_netlink_route(NMPCache * cache, - NMPObject * obj_hand_over, +NMPCacheOpsType nmp_cache_update_netlink_route(NMPCache *cache, + NMPObject *obj_hand_over, gboolean is_dump, guint16 nlmsgflags, const NMPObject **out_obj_old, const NMPObject **out_obj_new, const NMPObject **out_obj_replace, - gboolean * out_resync_required); -NMPCacheOpsType nmp_cache_update_link_udev(NMPCache * cache, + gboolean *out_resync_required); +NMPCacheOpsType nmp_cache_update_link_udev(NMPCache *cache, int ifindex, struct udev_device *udevice, - const NMPObject ** out_obj_old, - const NMPObject ** out_obj_new); -NMPCacheOpsType nmp_cache_update_link_master_connected(NMPCache * cache, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); +NMPCacheOpsType nmp_cache_update_link_master_connected(NMPCache *cache, int ifindex, const NMPObject **out_obj_old, const NMPObject **out_obj_new); static inline const NMDedupMultiEntry * -nmp_cache_reresolve_main_entry(NMPCache * cache, +nmp_cache_reresolve_main_entry(NMPCache *cache, const NMDedupMultiEntry *entry, - const NMPLookup * lookup) + const NMPLookup *lookup) { const NMDedupMultiEntry *main_entry; @@ -944,7 +944,7 @@ NMPCache *nmp_cache_new(NMDedupMultiIndex *multi_idx, gboolean use_udev); void nmp_cache_free(NMPCache *cache); static inline void -ASSERT_nmp_cache_ops(const NMPCache * cache, +ASSERT_nmp_cache_ops(const NMPCache *cache, NMPCacheOpsType ops_type, const NMPObject *obj_old, const NMPObject *obj_new) @@ -1024,7 +1024,7 @@ nm_platform_lookup_object(NMPlatform *platform, NMPObjectType obj_type, int ifin } static inline GPtrArray * -nm_platform_lookup_object_clone(NMPlatform * platform, +nm_platform_lookup_object_clone(NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPObjectPredicateFunc predicate, @@ -1046,7 +1046,7 @@ nm_platform_lookup_route_default(NMPlatform *platform, NMPObjectType obj_type) } static inline GPtrArray * -nm_platform_lookup_route_default_clone(NMPlatform * platform, +nm_platform_lookup_route_default_clone(NMPlatform *platform, NMPObjectType obj_type, NMPObjectPredicateFunc predicate, gpointer user_data) @@ -1071,7 +1071,7 @@ nm_platform_lookup_ip4_route_by_weak_id(NMPlatform *platform, } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_ip6_route_by_weak_id(NMPlatform * platform, +nm_platform_lookup_ip6_route_by_weak_id(NMPlatform *platform, const struct in6_addr *network, guint plen, guint32 metric, @@ -1085,7 +1085,7 @@ nm_platform_lookup_ip6_route_by_weak_id(NMPlatform * platform, } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_object_by_addr_family(NMPlatform * platform, +nm_platform_lookup_object_by_addr_family(NMPlatform *platform, NMPObjectType obj_type, int addr_family) { @@ -1112,6 +1112,21 @@ nmp_object_get_assume_config_once(const NMPObject *obj) } } +static inline gboolean +nmp_object_get_force_commit(const NMPObject *obj) +{ + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP6_ADDRESS: + return NMP_OBJECT_CAST_IP_ADDRESS(obj)->a_force_commit; + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + return NMP_OBJECT_CAST_IP_ROUTE(obj)->r_force_commit; + default: + return nm_assert_unreachable_val(FALSE); + } +} + static inline const char * nmp_object_link_get_ifname(const NMPObject *obj) { diff --git a/src/libnm-platform/nmp-route-manager.c b/src/libnm-platform/nmp-route-manager.c new file mode 100644 index 00000000..c31c9806 --- /dev/null +++ b/src/libnm-platform/nmp-route-manager.c @@ -0,0 +1,839 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nmp-route-manager.h" + +#include <linux/fib_rules.h> +#include <linux/rtnetlink.h> + +#include "libnm-log-core/nm-logging.h" +#include "libnm-std-aux/c-list-util.h" +#include "nmp-object.h" + +/*****************************************************************************/ + +struct _NMPRouteManager { + NMPlatform *platform; + GHashTable *by_obj; + GHashTable *by_user_tag; + GHashTable *by_data; + CList by_obj_lst_heads[3]; + guint ref_count; +}; + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG_PREFIX_NAME "route-manager" + +#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, LOGD_PLATFORM, _NMLOG_PREFIX_NAME, __VA_ARGS__) + +/*****************************************************************************/ + +static gboolean +NMP_IS_ROUTE_MANAGER(gpointer self) +{ + return self && ((NMPRouteManager *) self)->ref_count > 0 + && NM_IS_PLATFORM(((NMPRouteManager *) self)->platform); +} + +/*****************************************************************************/ + +typedef struct { + const NMPObject *obj; + gconstpointer user_tag; + CList obj_lst; + CList user_tag_lst; + + /* track_priority_val zero is special: those are weakly tracked rules. + * That means: NetworkManager will restore them only if it removed them earlier. + * But it will not remove or add them otherwise. + * + * Otherwise, the track_priority_val goes together with track_priority_present. + * In case of one rule being tracked multiple times (with different priorities), + * the one with higher priority wins. See _track_obj_data_get_best_data(). + * Then, the winning present state either enforces that the rule is present + * or absent. + * + * If a rules is not tracked at all, it is ignored by NetworkManager. Assuming + * that it was added externally by the user. But unlike weakly tracked rules, + * NM will *not* restore such rules if NetworkManager themself removed them. */ + guint32 track_priority_val; + bool track_priority_present : 1; + + bool dirty : 1; +} TrackData; + +typedef enum { + CONFIG_STATE_NONE = 0, + CONFIG_STATE_ADDED_BY_US = 1, + CONFIG_STATE_REMOVED_BY_US = 2, + + /* ConfigState encodes whether the rule was touched by us at all (CONFIG_STATE_NONE). + * + * Maybe we would only need to track whether we touched the rule at all. But we + * track it more in detail what we did: did we add it (CONFIG_STATE_ADDED_BY_US) + * or did we remove it (CONFIG_STATE_REMOVED_BY_US)? + * Finally, we need CONFIG_STATE_OWNED_BY_US, which means that we didn't actively + * add/remove it, but whenever we are about to undo the add/remove, we need to do it. + * In that sense, CONFIG_STATE_OWNED_BY_US is really just a flag that we unconditionally + * force the state next time when necessary. */ + CONFIG_STATE_OWNED_BY_US = 3, +} ConfigState; + +typedef struct { + const NMPObject *obj; + CList obj_lst_head; + + CList by_obj_lst; + + /* indicates whether we configured/removed the rule (during sync()). We need that, so + * if the rule gets untracked, that we know to remove/restore it. + * + * This makes NMPRouteManager stateful (beyond the configuration that indicates + * which rules are tracked). + * After a restart, NetworkManager would no longer remember which rules were added + * by us. + * + * That is partially fixed by NetworkManager taking over the rules that it + * actively configures (see %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ + ConfigState config_state; +} TrackObjData; + +typedef struct { + gconstpointer user_tag; + CList user_tag_lst_head; +} TrackUserTagData; + +/*****************************************************************************/ + +static void _track_data_untrack(NMPRouteManager *self, + TrackData *track_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us); + +/*****************************************************************************/ + +static CList * +_by_obj_lst_head(NMPRouteManager *self, NMPObjectType obj_type) +{ + G_STATIC_ASSERT(G_N_ELEMENTS(self->by_obj_lst_heads) == 3); + + switch (obj_type) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + return &self->by_obj_lst_heads[0]; + case NMP_OBJECT_TYPE_IP6_ROUTE: + return &self->by_obj_lst_heads[1]; + case NMP_OBJECT_TYPE_ROUTING_RULE: + return &self->by_obj_lst_heads[2]; + default: + return nm_assert_unreachable_val(NULL); + } +} + +/*****************************************************************************/ + +static void +_track_data_assert(const TrackData *track_data, gboolean linked) +{ + nm_assert(track_data); + nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(track_data->obj), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_ROUTING_RULE)); + nm_assert(nmp_object_is_visible(track_data->obj)); + nm_assert(track_data->user_tag); + nm_assert(!linked || !c_list_is_empty(&track_data->obj_lst)); + nm_assert(!linked || !c_list_is_empty(&track_data->user_tag_lst)); +} + +static guint +_track_data_hash(gconstpointer data) +{ + const TrackData *track_data = data; + NMHashState h; + + _track_data_assert(track_data, FALSE); + + nm_hash_init(&h, 269297543u); + nmp_object_id_hash_update(track_data->obj, &h); + nm_hash_update_val(&h, track_data->user_tag); + return nm_hash_complete(&h); +} + +static gboolean +_track_data_equal(gconstpointer data_a, gconstpointer data_b) +{ + const TrackData *track_data_a = data_a; + const TrackData *track_data_b = data_b; + + _track_data_assert(track_data_a, FALSE); + _track_data_assert(track_data_b, FALSE); + + return track_data_a->user_tag == track_data_b->user_tag + && nmp_object_id_equal(track_data_a->obj, track_data_b->obj); +} + +static void +_track_data_destroy(gpointer data) +{ + TrackData *track_data = data; + + _track_data_assert(track_data, FALSE); + + c_list_unlink_stale(&track_data->obj_lst); + c_list_unlink_stale(&track_data->user_tag_lst); + nmp_object_unref(track_data->obj); + nm_g_slice_free(track_data); +} + +static const TrackData * +_track_obj_data_get_best_data(TrackObjData *obj_data) +{ + TrackData *track_data; + const TrackData *td_best = NULL; + + c_list_for_each_entry (track_data, &obj_data->obj_lst_head, obj_lst) { + _track_data_assert(track_data, TRUE); + + if (td_best) { + if (td_best->track_priority_val > track_data->track_priority_val) + continue; + if (td_best->track_priority_val == track_data->track_priority_val) { + if (td_best->track_priority_present || !track_data->track_priority_present) { + /* if the priorities are identical, then "present" wins over + * "!present" (absent). */ + continue; + } + } + } + + td_best = track_data; + } + + return td_best; +} + +static guint +_track_obj_data_hash(gconstpointer data) +{ + const TrackObjData *obj_data = data; + + return nmp_object_id_hash(obj_data->obj); +} + +static gboolean +_track_obj_data_equal(gconstpointer data_a, gconstpointer data_b) +{ + const TrackObjData *obj_data_a = data_a; + const TrackObjData *obj_data_b = data_b; + + return nmp_object_id_equal(obj_data_a->obj, obj_data_b->obj); +} + +static void +_track_obj_data_destroy(gpointer data) +{ + TrackObjData *obj_data = data; + + c_list_unlink_stale(&obj_data->obj_lst_head); + c_list_unlink_stale(&obj_data->by_obj_lst); + nmp_object_unref(obj_data->obj); + nm_g_slice_free(obj_data); +} + +static void +_track_user_tag_data_destroy(gpointer data) +{ + TrackUserTagData *user_tag_data = data; + + c_list_unlink_stale(&user_tag_data->user_tag_lst_head); + nm_g_slice_free(user_tag_data); +} + +static TrackData * +_track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user_tag) +{ + TrackData track_data_needle = { + .obj = obj, + .user_tag = user_tag, + }; + + return g_hash_table_lookup(by_data, &track_data_needle); +} + +/*****************************************************************************/ + +/** + * nmp_route_manager_track: + * @self: the #NMPRouteManager instance + * @obj_type: the NMPObjectType of @obj that we are tracking. + * @obj: the NMPlatformObject (of type NMPObjectType) to track. Usually + * a #NMPlatformRoutingRule, #NMPlatformIP4Route or #NMPlatformIP6Route + * pointer. + * @track_priority: the priority for tracking the rule. Note that + * negative values indicate a forced absence of the rule. Priorities + * are compared with their absolute values (with higher absolute + * value being more important). For example, if you track the same + * rule twice, once with priority -5 and +10, then the rule is + * present (because the positive number is more important). + * The special value 0 indicates weakly-tracked rules. + * @user_tag: the tag associated with tracking this rule. The same tag + * must be used to untrack the rule later. + * @user_tag_untrack: if not %NULL, at the same time untrack this user-tag + * for the same rule. Note that this is different from a plain nmp_route_manager_untrack_rule(), + * because it enforces ownership of the now tracked rule. On the other hand, + * a plain nmp_route_manager_untrack_rule() merely forgets about the tracking. + * The purpose here is to set this to %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. + * + * Returns: %TRUE, if something changed. + */ +gboolean +nmp_route_manager_track(NMPRouteManager *self, + NMPObjectType obj_type, + gconstpointer obj, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) +{ + NMPObject obj_stack; + const NMPObject *p_obj_stack; + TrackData *track_data; + TrackObjData *obj_data; + TrackUserTagData *user_tag_data; + gboolean changed = FALSE; + gboolean changed_untrack = FALSE; + guint32 track_priority_val; + gboolean track_priority_present; + + g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(obj, FALSE); + g_return_val_if_fail(user_tag, FALSE); + + /* The route must not be tied to an interface. We can only handle here + * blackhole/unreachable/prohibit route types. */ + g_return_val_if_fail( + obj_type == NMP_OBJECT_TYPE_ROUTING_RULE + || (NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) + && ((const NMPlatformIPRoute *) obj)->ifindex == 0), + FALSE); + + nm_assert(track_priority != G_MININT32); + + p_obj_stack = nmp_object_stackinit(&obj_stack, obj_type, obj); + + nm_assert(nmp_object_is_visible(p_obj_stack)); + + if (track_priority >= 0) { + track_priority_val = track_priority; + track_priority_present = TRUE; + } else { + track_priority_val = -track_priority; + track_priority_present = FALSE; + } + + track_data = _track_data_lookup(self->by_data, p_obj_stack, user_tag); + + if (!track_data) { + track_data = g_slice_new(TrackData); + *track_data = (TrackData){ + .obj = nm_dedup_multi_index_obj_intern(nm_platform_get_multi_idx(self->platform), + p_obj_stack), + .user_tag = user_tag, + .track_priority_val = track_priority_val, + .track_priority_present = track_priority_present, + .dirty = FALSE, + }; + g_hash_table_add(self->by_data, track_data); + + obj_data = g_hash_table_lookup(self->by_obj, &track_data->obj); + if (!obj_data) { + obj_data = g_slice_new(TrackObjData); + *obj_data = (TrackObjData){ + .obj = nmp_object_ref(track_data->obj), + .obj_lst_head = C_LIST_INIT(obj_data->obj_lst_head), + .config_state = CONFIG_STATE_NONE, + }; + g_hash_table_add(self->by_obj, obj_data); + c_list_link_tail(_by_obj_lst_head(self, obj_type), &obj_data->by_obj_lst); + } + c_list_link_tail(&obj_data->obj_lst_head, &track_data->obj_lst); + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &track_data->user_tag); + if (!user_tag_data) { + user_tag_data = g_slice_new(TrackUserTagData); + *user_tag_data = (TrackUserTagData){ + .user_tag = user_tag, + .user_tag_lst_head = C_LIST_INIT(user_tag_data->user_tag_lst_head), + }; + g_hash_table_add(self->by_user_tag, user_tag_data); + } + c_list_link_tail(&user_tag_data->user_tag_lst_head, &track_data->user_tag_lst); + changed = TRUE; + } else { + track_data->dirty = FALSE; + if (track_data->track_priority_val != track_priority_val + || track_data->track_priority_present != track_priority_present) { + track_data->track_priority_val = track_priority_val; + track_data->track_priority_present = track_priority_present; + changed = TRUE; + } + } + + if (user_tag_untrack) { + if (user_tag != user_tag_untrack) { + TrackData *track_data_untrack; + + track_data_untrack = _track_data_lookup(self->by_data, p_obj_stack, user_tag_untrack); + if (track_data_untrack) { + _track_data_untrack(self, track_data_untrack, FALSE, TRUE); + changed_untrack = TRUE; + } + } else + nm_assert_not_reached(); + } + + _track_data_assert(track_data, TRUE); + + if (changed) { + _LOGD("track [" NM_HASH_OBFUSCATE_PTR_FMT ",%s%u] %s \"%s\"", + NM_HASH_OBFUSCATE_PTR(track_data->user_tag), + (track_data->track_priority_val == 0 + ? "" + : (track_data->track_priority_present ? "+" : "-")), + (guint) track_data->track_priority_val, + NMP_OBJECT_GET_CLASS(track_data->obj)->obj_type_name, + nmp_object_to_string(track_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + } + + return changed || changed_untrack; +} + +static void +_track_data_untrack(NMPRouteManager *self, + TrackData *track_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us) +{ + TrackObjData *obj_data; + + nm_assert(NMP_IS_ROUTE_MANAGER(self)); + _track_data_assert(track_data, TRUE); + nm_assert(self->by_data); + nm_assert(g_hash_table_lookup(self->by_data, track_data) == track_data); + + _LOGD("untrack [" NM_HASH_OBFUSCATE_PTR_FMT "] %s \"%s\"", + NM_HASH_OBFUSCATE_PTR(track_data->user_tag), + NMP_OBJECT_GET_CLASS(track_data->obj)->obj_type_name, + nmp_object_to_string(track_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + +#if NM_MORE_ASSERTS + { + TrackUserTagData *user_tag_data; + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &track_data->user_tag); + nm_assert(user_tag_data); + nm_assert(c_list_contains(&user_tag_data->user_tag_lst_head, &track_data->user_tag_lst)); + } +#endif + + nm_assert(!c_list_is_empty(&track_data->user_tag_lst)); + + obj_data = g_hash_table_lookup(self->by_obj, &track_data->obj); + nm_assert(obj_data); + nm_assert(c_list_contains(&obj_data->obj_lst_head, &track_data->obj_lst)); + nm_assert(obj_data == g_hash_table_lookup(self->by_obj, &track_data->obj)); + + if (make_owned_by_us) { + if (obj_data->config_state == CONFIG_STATE_NONE) { + /* we need to mark this entry that it requires a touch on the next + * sync. */ + obj_data->config_state = CONFIG_STATE_OWNED_BY_US; + } + } else if (remove_user_tag_data && c_list_length_is(&track_data->user_tag_lst, 1)) + g_hash_table_remove(self->by_user_tag, &track_data->user_tag); + + /* if obj_data is marked to be "added_by_us" or "removed_by_us", we need to keep this entry + * around for the next sync -- so that we can undo what we did earlier. */ + if (obj_data->config_state == CONFIG_STATE_NONE && c_list_length_is(&track_data->obj_lst, 1)) + g_hash_table_remove(self->by_obj, &track_data->obj); + + g_hash_table_remove(self->by_data, track_data); +} + +gboolean +nmp_route_manager_untrack(NMPRouteManager *self, + NMPObjectType obj_type, + gconstpointer obj, + gconstpointer user_tag) +{ + NMPObject obj_stack; + const NMPObject *p_obj_stack; + TrackData *track_data; + gboolean changed = FALSE; + + g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + nm_assert(NM_IN_SET(obj_type, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_ROUTING_RULE)); + g_return_val_if_fail(obj, FALSE); + g_return_val_if_fail(user_tag, FALSE); + + p_obj_stack = nmp_object_stackinit(&obj_stack, obj_type, obj); + + nm_assert(nmp_object_is_visible(p_obj_stack)); + + track_data = _track_data_lookup(self->by_data, p_obj_stack, user_tag); + if (track_data) { + _track_data_untrack(self, track_data, TRUE, FALSE); + changed = TRUE; + } + + return changed; +} + +void +nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag) +{ + TrackData *track_data; + TrackUserTagData *user_tag_data; + + g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(user_tag); + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); + if (!user_tag_data) + return; + + c_list_for_each_entry (track_data, &user_tag_data->user_tag_lst_head, user_tag_lst) + track_data->dirty = TRUE; +} + +gboolean +nmp_route_manager_untrack_all(NMPRouteManager *self, + gconstpointer user_tag, + gboolean all /* or only dirty */, + gboolean make_survivors_dirty) +{ + TrackData *track_data; + TrackData *track_data_safe; + TrackUserTagData *user_tag_data; + gboolean changed = FALSE; + + g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(user_tag, FALSE); + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); + if (!user_tag_data) + return FALSE; + + c_list_for_each_entry_safe (track_data, + track_data_safe, + &user_tag_data->user_tag_lst_head, + user_tag_lst) { + if (all || track_data->dirty) { + _track_data_untrack(self, track_data, FALSE, FALSE); + changed = TRUE; + continue; + } + if (make_survivors_dirty) + track_data->dirty = TRUE; + } + if (c_list_is_empty(&user_tag_data->user_tag_lst_head)) + g_hash_table_remove(self->by_user_tag, user_tag_data); + + return changed; +} + +/*****************************************************************************/ + +void +nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted) +{ + const NMDedupMultiHeadEntry *pl_head_entry; + NMDedupMultiIter pl_iter; + const NMPObject *plobj; + gs_unref_ptrarray GPtrArray *objs_to_delete = NULL; + TrackObjData *obj_data; + TrackObjData *obj_data_safe; + CList *by_obj_lst_head; + guint i; + const TrackData *td_best; + + g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NM_IN_SET(obj_type, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_ROUTING_RULE)); + + _LOGD("sync %s%s", + nmp_class_from_type(obj_type)->obj_type_name, + keep_deleted ? " (don't remove any)" : ""); + + if (obj_type == NMP_OBJECT_TYPE_ROUTING_RULE) + pl_head_entry = nm_platform_lookup_obj_type(self->platform, obj_type); + else + pl_head_entry = nm_platform_lookup_object(self->platform, obj_type, 0); + + if (pl_head_entry) { + nmp_cache_iter_for_each (&pl_iter, pl_head_entry, &plobj) { + obj_data = g_hash_table_lookup(self->by_obj, &plobj); + + if (!obj_data) { + /* this obj is not tracked. It was externally added, hence we + * ignore it. */ + continue; + } + + td_best = _track_obj_data_get_best_data(obj_data); + if (td_best) { + if (td_best->track_priority_present) { + if (obj_data->config_state == CONFIG_STATE_OWNED_BY_US) + obj_data->config_state = CONFIG_STATE_ADDED_BY_US; + continue; + } + if (td_best->track_priority_val == 0) { + if (!NM_IN_SET(obj_data->config_state, + CONFIG_STATE_ADDED_BY_US, + CONFIG_STATE_OWNED_BY_US)) { + obj_data->config_state = CONFIG_STATE_NONE; + continue; + } + obj_data->config_state = CONFIG_STATE_NONE; + } + } + + if (keep_deleted) { + _LOGD("forget/leak object added by us: %s \"%s\"", + NMP_OBJECT_GET_CLASS(plobj)->obj_type_name, + nmp_object_to_string(plobj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + continue; + } + + if (!objs_to_delete) + objs_to_delete = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + + g_ptr_array_add(objs_to_delete, (gpointer) nmp_object_ref(plobj)); + + obj_data->config_state = CONFIG_STATE_REMOVED_BY_US; + } + } + + if (objs_to_delete) { + for (i = 0; i < objs_to_delete->len; i++) + nm_platform_object_delete(self->platform, objs_to_delete->pdata[i]); + } + + by_obj_lst_head = _by_obj_lst_head(self, obj_type); + + c_list_for_each_entry_safe (obj_data, obj_data_safe, by_obj_lst_head, by_obj_lst) { + nm_assert(NMP_OBJECT_GET_TYPE(obj_data->obj) == obj_type); + + td_best = _track_obj_data_get_best_data(obj_data); + + if (!td_best) { + g_hash_table_remove(self->by_obj, obj_data); + continue; + } + + if (!td_best->track_priority_present) { + if (obj_data->config_state == CONFIG_STATE_OWNED_BY_US) + obj_data->config_state = CONFIG_STATE_REMOVED_BY_US; + continue; + } + if (td_best->track_priority_val == 0) { + if (!NM_IN_SET(obj_data->config_state, + CONFIG_STATE_REMOVED_BY_US, + CONFIG_STATE_OWNED_BY_US)) { + obj_data->config_state = CONFIG_STATE_NONE; + continue; + } + obj_data->config_state = CONFIG_STATE_NONE; + } + + plobj = + nm_platform_lookup_obj(self->platform, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj_data->obj); + if (plobj) + continue; + + obj_data->config_state = CONFIG_STATE_ADDED_BY_US; + + if (obj_type == NMP_OBJECT_TYPE_ROUTING_RULE) { + nm_platform_routing_rule_add(self->platform, + NMP_NLM_FLAG_ADD, + NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj)); + } else + nm_platform_ip_route_add(self->platform, NMP_NLM_FLAG_APPEND, obj_data->obj); + } +} + +/*****************************************************************************/ + +void +nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, + NMPlatform *platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag) +{ + NMPLookup lookup; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject *o; + + g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + + if (!platform) + platform = self->platform; + else + g_return_if_fail(NM_IS_PLATFORM(platform)); + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + head_entry = nm_platform_lookup(platform, &lookup); + nmp_cache_iter_for_each (&iter, head_entry, &o) { + const NMPlatformRoutingRule *rr = NMP_OBJECT_CAST_ROUTING_RULE(o); + + if (addr_family != AF_UNSPEC && rr->addr_family != addr_family) + continue; + + nmp_route_manager_track_rule(self, rr, tracking_priority, user_tag, NULL); + } +} + +/*****************************************************************************/ + +void +nmp_route_manager_track_rule_default(NMPRouteManager *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag) +{ + g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + /* track the default rules. See also `man ip-rule`. */ + + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { + nmp_route_manager_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_route_manager_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_route_manager_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32767, + .table = RT_TABLE_DEFAULT, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + } + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { + nmp_route_manager_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_route_manager_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + } +} + +/*****************************************************************************/ + +NMPRouteManager * +nmp_route_manager_new(NMPlatform *platform) +{ + NMPRouteManager *self; + + g_return_val_if_fail(NM_IS_PLATFORM(platform), NULL); + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(TrackUserTagData, user_tag) == 0); + + self = g_slice_new(NMPRouteManager); + *self = (NMPRouteManager){ + .ref_count = 1, + .platform = g_object_ref(platform), + .by_data = + g_hash_table_new_full(_track_data_hash, _track_data_equal, NULL, _track_data_destroy), + .by_obj = g_hash_table_new_full(_track_obj_data_hash, + _track_obj_data_equal, + NULL, + _track_obj_data_destroy), + .by_user_tag = g_hash_table_new_full(nm_pdirect_hash, + nm_pdirect_equal, + NULL, + _track_user_tag_data_destroy), + .by_obj_lst_heads[0] = C_LIST_INIT(self->by_obj_lst_heads[0]), + .by_obj_lst_heads[1] = C_LIST_INIT(self->by_obj_lst_heads[1]), + .by_obj_lst_heads[2] = C_LIST_INIT(self->by_obj_lst_heads[2]), + }; + return self; +} + +NMPRouteManager * +nmp_route_manager_ref(NMPRouteManager *self) +{ + g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), NULL); + + self->ref_count++; + return self; +} + +void +nmp_route_manager_unref(NMPRouteManager *self) +{ + g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + + if (--self->ref_count > 0) + return; + + g_hash_table_destroy(self->by_user_tag); + g_hash_table_destroy(self->by_obj); + g_hash_table_destroy(self->by_data); + nm_assert(c_list_is_empty(&self->by_obj_lst_heads[0])); + nm_assert(c_list_is_empty(&self->by_obj_lst_heads[1])); + nm_assert(c_list_is_empty(&self->by_obj_lst_heads[2])); + g_object_unref(self->platform); + nm_g_slice_free(self); +} diff --git a/src/libnm-platform/nmp-route-manager.h b/src/libnm-platform/nmp-route-manager.h new file mode 100644 index 00000000..97ec3840 --- /dev/null +++ b/src/libnm-platform/nmp-route-manager.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NMP_ROUTE_MANAGER_H__ +#define __NMP_ROUTE_MANAGER_H__ + +#include "nm-platform.h" + +/*****************************************************************************/ + +#define NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_route_manager_new) + +typedef struct _NMPRouteManager NMPRouteManager; + +NMPRouteManager *nmp_route_manager_new(NMPlatform *platform); + +NMPRouteManager *nmp_route_manager_ref(NMPRouteManager *self); +void nmp_route_manager_unref(NMPRouteManager *self); + +#define nm_auto_unref_route_manager nm_auto(_nmp_route_manager_unref) +NM_AUTO_DEFINE_FCN0(NMPRouteManager *, _nmp_route_manager_unref, nmp_route_manager_unref); + +gboolean nmp_route_manager_track(NMPRouteManager *self, + NMPObjectType obj_type, + gconstpointer obj, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack); + +static inline gboolean +nmp_route_manager_track_rule(NMPRouteManager *self, + const NMPlatformRoutingRule *routing_rule, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) +{ + return nmp_route_manager_track(self, + NMP_OBJECT_TYPE_ROUTING_RULE, + routing_rule, + track_priority, + user_tag, + user_tag_untrack); +} + +void nmp_route_manager_track_rule_default(NMPRouteManager *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag); + +void nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, + NMPlatform *platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag); + +gboolean nmp_route_manager_untrack(NMPRouteManager *self, + NMPObjectType obj_type, + gconstpointer obj, + gconstpointer user_tag); + +static inline gboolean +nmp_route_manager_untrack_rule(NMPRouteManager *self, + const NMPlatformRoutingRule *routing_rule, + gconstpointer user_tag) +{ + return nmp_route_manager_untrack(self, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule, user_tag); +} + +void nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag); + +gboolean nmp_route_manager_untrack_all(NMPRouteManager *self, + gconstpointer user_tag, + gboolean all /* or only dirty */, + gboolean make_survivors_dirty); + +void nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted); + +/*****************************************************************************/ + +#endif /* __NMP_ROUTE_MANAGER_H__ */ diff --git a/src/libnm-platform/nmp-rules-manager.c b/src/libnm-platform/nmp-rules-manager.c deleted file mode 100644 index 636c90b2..00000000 --- a/src/libnm-platform/nmp-rules-manager.c +++ /dev/null @@ -1,809 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" - -#include "nmp-rules-manager.h" - -#include <linux/fib_rules.h> -#include <linux/rtnetlink.h> - -#include "libnm-log-core/nm-logging.h" -#include "libnm-std-aux/c-list-util.h" -#include "nmp-object.h" - -/*****************************************************************************/ - -struct _NMPRulesManager { - NMPlatform *platform; - GHashTable *by_obj; - GHashTable *by_user_tag; - GHashTable *by_data; - guint ref_count; -}; - -/*****************************************************************************/ - -static void _rules_init(NMPRulesManager *self); - -/*****************************************************************************/ - -#define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG_PREFIX_NAME "rules-manager" - -#define _NMLOG(level, ...) \ - G_STMT_START \ - { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ - _nm_log(__level, \ - _NMLOG_DOMAIN, \ - 0, \ - NULL, \ - NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } \ - G_STMT_END - -/*****************************************************************************/ - -static gboolean -NMP_IS_RULES_MANAGER(gpointer self) -{ - return self && ((NMPRulesManager *) self)->ref_count > 0 - && NM_IS_PLATFORM(((NMPRulesManager *) self)->platform); -} - -#define _USER_TAG_LOG(user_tag) nm_hash_obfuscate_ptr(1240261787u, (user_tag)) - -/*****************************************************************************/ - -typedef struct { - const NMPObject *obj; - gconstpointer user_tag; - CList obj_lst; - CList user_tag_lst; - - /* track_priority_val zero is special: those are weakly tracked rules. - * That means: NetworkManager will restore them only if it removed them earlier. - * But it will not remove or add them otherwise. - * - * Otherwise, the track_priority_val goes together with track_priority_present. - * In case of one rule being tracked multiple times (with different priorities), - * the one with higher priority wins. See _rules_obj_get_best_data(). - * Then, the winning present state either enforces that the rule is present - * or absent. - * - * If a rules is not tracked at all, it is ignored by NetworkManager. Assuming - * that it was added externally by the user. But unlike weakly tracked rules, - * NM will *not* restore such rules if NetworkManager themself removed them. */ - guint32 track_priority_val; - bool track_priority_present : 1; - - bool dirty : 1; -} RulesData; - -typedef enum { - CONFIG_STATE_NONE = 0, - CONFIG_STATE_ADDED_BY_US = 1, - CONFIG_STATE_REMOVED_BY_US = 2, - - /* ConfigState encodes whether the rule was touched by us at all (CONFIG_STATE_NONE). - * - * Maybe we would only need to track whether we touched the rule at all. But we - * track it more in detail what we did: did we add it (CONFIG_STATE_ADDED_BY_US) - * or did we remove it (CONFIG_STATE_REMOVED_BY_US)? - * Finally, we need CONFIG_STATE_OWNED_BY_US, which means that we didn't actively - * add/remove it, but whenever we are about to undo the add/remove, we need to do it. - * In that sense, CONFIG_STATE_OWNED_BY_US is really just a flag that we unconditionally - * force the state next time when necessary. */ - CONFIG_STATE_OWNED_BY_US = 3, -} ConfigState; - -typedef struct { - const NMPObject *obj; - CList obj_lst_head; - - /* indicates whether we configured/removed the rule (during sync()). We need that, so - * if the rule gets untracked, that we know to remove/restore it. - * - * This makes NMPRulesManager stateful (beyond the configuration that indicates - * which rules are tracked). - * After a restart, NetworkManager would no longer remember which rules were added - * by us. - * - * That is partially fixed by NetworkManager taking over the rules that it - * actively configures (see %NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ - ConfigState config_state; -} RulesObjData; - -typedef struct { - gconstpointer user_tag; - CList user_tag_lst_head; -} RulesUserTagData; - -/*****************************************************************************/ - -static void _rules_data_untrack(NMPRulesManager *self, - RulesData * rules_data, - gboolean remove_user_tag_data, - gboolean make_owned_by_us); - -/*****************************************************************************/ - -static void -_rules_data_assert(const RulesData *rules_data, gboolean linked) -{ - nm_assert(rules_data); - nm_assert(NMP_OBJECT_GET_TYPE(rules_data->obj) == NMP_OBJECT_TYPE_ROUTING_RULE); - nm_assert(nmp_object_is_visible(rules_data->obj)); - nm_assert(rules_data->user_tag); - nm_assert(!linked || !c_list_is_empty(&rules_data->obj_lst)); - nm_assert(!linked || !c_list_is_empty(&rules_data->user_tag_lst)); -} - -static guint -_rules_data_hash(gconstpointer data) -{ - const RulesData *rules_data = data; - NMHashState h; - - _rules_data_assert(rules_data, FALSE); - - nm_hash_init(&h, 269297543u); - nm_platform_routing_rule_hash_update(NMP_OBJECT_CAST_ROUTING_RULE(rules_data->obj), - NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, - &h); - nm_hash_update_val(&h, rules_data->user_tag); - return nm_hash_complete(&h); -} - -static gboolean -_rules_data_equal(gconstpointer data_a, gconstpointer data_b) -{ - const RulesData *rules_data_a = data_a; - const RulesData *rules_data_b = data_b; - - _rules_data_assert(rules_data_a, FALSE); - _rules_data_assert(rules_data_b, FALSE); - - return rules_data_a->user_tag == rules_data_b->user_tag - && (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(rules_data_a->obj), - NMP_OBJECT_CAST_ROUTING_RULE(rules_data_b->obj), - NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) - == 0); -} - -static void -_rules_data_destroy(gpointer data) -{ - RulesData *rules_data = data; - - _rules_data_assert(rules_data, FALSE); - - c_list_unlink_stale(&rules_data->obj_lst); - c_list_unlink_stale(&rules_data->user_tag_lst); - nmp_object_unref(rules_data->obj); - g_slice_free(RulesData, rules_data); -} - -static const RulesData * -_rules_obj_get_best_data(RulesObjData *obj_data) -{ - RulesData * rules_data; - const RulesData *rd_best = NULL; - - c_list_for_each_entry (rules_data, &obj_data->obj_lst_head, obj_lst) { - _rules_data_assert(rules_data, TRUE); - - if (rd_best) { - if (rd_best->track_priority_val > rules_data->track_priority_val) - continue; - if (rd_best->track_priority_val == rules_data->track_priority_val) { - if (rd_best->track_priority_present || !rules_data->track_priority_present) { - /* if the priorities are identical, then "present" wins over - * "!present" (absent). */ - continue; - } - } - } - - rd_best = rules_data; - } - - return rd_best; -} - -static guint -_rules_obj_hash(gconstpointer data) -{ - const RulesObjData *obj_data = data; - NMHashState h; - - nm_hash_init(&h, 432817559u); - nm_platform_routing_rule_hash_update(NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj), - NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, - &h); - return nm_hash_complete(&h); -} - -static gboolean -_rules_obj_equal(gconstpointer data_a, gconstpointer data_b) -{ - const RulesObjData *obj_data_a = data_a; - const RulesObjData *obj_data_b = data_b; - - return (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(obj_data_a->obj), - NMP_OBJECT_CAST_ROUTING_RULE(obj_data_b->obj), - NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) - == 0); -} - -static void -_rules_obj_destroy(gpointer data) -{ - RulesObjData *obj_data = data; - - c_list_unlink_stale(&obj_data->obj_lst_head); - nmp_object_unref(obj_data->obj); - g_slice_free(RulesObjData, obj_data); -} - -static guint -_rules_user_tag_hash(gconstpointer data) -{ - const RulesUserTagData *user_tag_data = data; - - return nm_hash_val(644693447u, user_tag_data->user_tag); -} - -static gboolean -_rules_user_tag_equal(gconstpointer data_a, gconstpointer data_b) -{ - const RulesUserTagData *user_tag_data_a = data_a; - const RulesUserTagData *user_tag_data_b = data_b; - - return user_tag_data_a->user_tag == user_tag_data_b->user_tag; -} - -static void -_rules_user_tag_destroy(gpointer data) -{ - RulesUserTagData *user_tag_data = data; - - c_list_unlink_stale(&user_tag_data->user_tag_lst_head); - g_slice_free(RulesUserTagData, user_tag_data); -} - -static RulesData * -_rules_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user_tag) -{ - RulesData rules_data_needle = { - .obj = obj, - .user_tag = user_tag, - }; - - return g_hash_table_lookup(by_data, &rules_data_needle); -} - -/** - * nmp_rules_manager_track: - * @self: the #NMPRulesManager instance - * @routing_rule: the #NMPlatformRoutingRule to track or untrack - * @track_priority: the priority for tracking the rule. Note that - * negative values indicate a forced absence of the rule. Priorities - * are compared with their absolute values (with higher absolute - * value being more important). For example, if you track the same - * rule twice, once with priority -5 and +10, then the rule is - * present (because the positive number is more important). - * The special value 0 indicates weakly-tracked rules. - * @user_tag: the tag associated with tracking this rule. The same tag - * must be used to untrack the rule later. - * @user_tag_untrack: if not %NULL, at the same time untrack this user-tag - * for the same rule. Note that this is different from a plain nmp_rules_manager_untrack(), - * because it enforces ownership of the now tracked rule. On the other hand, - * a plain nmp_rules_manager_untrack() merely forgets about the tracking. - * The purpose here is to set this to %NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. - */ -void -nmp_rules_manager_track(NMPRulesManager * self, - const NMPlatformRoutingRule *routing_rule, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack) -{ - NMPObject obj_stack; - const NMPObject * p_obj_stack; - RulesData * rules_data; - RulesObjData * obj_data; - RulesUserTagData *user_tag_data; - gboolean changed = FALSE; - guint32 track_priority_val; - gboolean track_priority_present; - - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - g_return_if_fail(routing_rule); - g_return_if_fail(user_tag); - nm_assert(track_priority != G_MININT32); - - _rules_init(self); - - p_obj_stack = nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule); - - nm_assert(nmp_object_is_visible(p_obj_stack)); - - if (track_priority >= 0) { - track_priority_val = track_priority; - track_priority_present = TRUE; - } else { - track_priority_val = -track_priority; - track_priority_present = FALSE; - } - - rules_data = _rules_data_lookup(self->by_data, p_obj_stack, user_tag); - - if (!rules_data) { - rules_data = g_slice_new(RulesData); - *rules_data = (RulesData){ - .obj = nm_dedup_multi_index_obj_intern(nm_platform_get_multi_idx(self->platform), - p_obj_stack), - .user_tag = user_tag, - .track_priority_val = track_priority_val, - .track_priority_present = track_priority_present, - .dirty = FALSE, - }; - g_hash_table_add(self->by_data, rules_data); - - obj_data = g_hash_table_lookup(self->by_obj, &rules_data->obj); - if (!obj_data) { - obj_data = g_slice_new(RulesObjData); - *obj_data = (RulesObjData){ - .obj = nmp_object_ref(rules_data->obj), - .obj_lst_head = C_LIST_INIT(obj_data->obj_lst_head), - .config_state = CONFIG_STATE_NONE, - }; - g_hash_table_add(self->by_obj, obj_data); - } - c_list_link_tail(&obj_data->obj_lst_head, &rules_data->obj_lst); - - user_tag_data = g_hash_table_lookup(self->by_user_tag, &rules_data->user_tag); - if (!user_tag_data) { - user_tag_data = g_slice_new(RulesUserTagData); - *user_tag_data = (RulesUserTagData){ - .user_tag = user_tag, - .user_tag_lst_head = C_LIST_INIT(user_tag_data->user_tag_lst_head), - }; - g_hash_table_add(self->by_user_tag, user_tag_data); - } - c_list_link_tail(&user_tag_data->user_tag_lst_head, &rules_data->user_tag_lst); - changed = TRUE; - } else { - rules_data->dirty = FALSE; - if (rules_data->track_priority_val != track_priority_val - || rules_data->track_priority_present != track_priority_present) { - rules_data->track_priority_val = track_priority_val; - rules_data->track_priority_present = track_priority_present; - changed = TRUE; - } - } - - if (user_tag_untrack) { - if (user_tag != user_tag_untrack) { - RulesData *rules_data_untrack; - - rules_data_untrack = _rules_data_lookup(self->by_data, p_obj_stack, user_tag_untrack); - if (rules_data_untrack) - _rules_data_untrack(self, rules_data_untrack, FALSE, TRUE); - } else - nm_assert_not_reached(); - } - - _rules_data_assert(rules_data, TRUE); - - if (changed) { - _LOGD("routing-rule: track [" NM_HASH_OBFUSCATE_PTR_FMT ",%s%u] \"%s\")", - _USER_TAG_LOG(rules_data->user_tag), - (rules_data->track_priority_val == 0 - ? "" - : (rules_data->track_priority_present ? "+" : "-")), - (guint) rules_data->track_priority_val, - nmp_object_to_string(rules_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - } -} - -static void -_rules_data_untrack(NMPRulesManager *self, - RulesData * rules_data, - gboolean remove_user_tag_data, - gboolean make_owned_by_us) -{ - RulesObjData *obj_data; - - nm_assert(NMP_IS_RULES_MANAGER(self)); - _rules_data_assert(rules_data, TRUE); - nm_assert(self->by_data); - nm_assert(g_hash_table_lookup(self->by_data, rules_data) == rules_data); - - _LOGD("routing-rule: untrack [" NM_HASH_OBFUSCATE_PTR_FMT "] \"%s\"", - _USER_TAG_LOG(rules_data->user_tag), - nmp_object_to_string(rules_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - -#if NM_MORE_ASSERTS - { - RulesUserTagData *user_tag_data; - - user_tag_data = g_hash_table_lookup(self->by_user_tag, &rules_data->user_tag); - nm_assert(user_tag_data); - nm_assert(c_list_contains(&user_tag_data->user_tag_lst_head, &rules_data->user_tag_lst)); - } -#endif - - nm_assert(!c_list_is_empty(&rules_data->user_tag_lst)); - - obj_data = g_hash_table_lookup(self->by_obj, &rules_data->obj); - nm_assert(obj_data); - nm_assert(c_list_contains(&obj_data->obj_lst_head, &rules_data->obj_lst)); - nm_assert(obj_data == g_hash_table_lookup(self->by_obj, &rules_data->obj)); - - if (make_owned_by_us) { - if (obj_data->config_state == CONFIG_STATE_NONE) { - /* we need to mark this entry that it requires a touch on the next - * sync. */ - obj_data->config_state = CONFIG_STATE_OWNED_BY_US; - } - } else if (remove_user_tag_data && c_list_length_is(&rules_data->user_tag_lst, 1)) - g_hash_table_remove(self->by_user_tag, &rules_data->user_tag); - - /* if obj_data is marked to be "added_by_us" or "removed_by_us", we need to keep this entry - * around for the next sync -- so that we can undo what we did earlier. */ - if (obj_data->config_state == CONFIG_STATE_NONE && c_list_length_is(&rules_data->obj_lst, 1)) - g_hash_table_remove(self->by_obj, &rules_data->obj); - - g_hash_table_remove(self->by_data, rules_data); -} - -void -nmp_rules_manager_untrack(NMPRulesManager * self, - const NMPlatformRoutingRule *routing_rule, - gconstpointer user_tag) -{ - NMPObject obj_stack; - const NMPObject *p_obj_stack; - RulesData * rules_data; - - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - g_return_if_fail(routing_rule); - g_return_if_fail(user_tag); - - _rules_init(self); - - p_obj_stack = nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule); - - nm_assert(nmp_object_is_visible(p_obj_stack)); - - rules_data = _rules_data_lookup(self->by_data, p_obj_stack, user_tag); - if (rules_data) - _rules_data_untrack(self, rules_data, TRUE, FALSE); -} - -void -nmp_rules_manager_set_dirty(NMPRulesManager *self, gconstpointer user_tag) -{ - RulesData * rules_data; - RulesUserTagData *user_tag_data; - - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - g_return_if_fail(user_tag); - - if (!self->by_data) - return; - - user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); - if (!user_tag_data) - return; - - c_list_for_each_entry (rules_data, &user_tag_data->user_tag_lst_head, user_tag_lst) - rules_data->dirty = TRUE; -} - -void -nmp_rules_manager_untrack_all(NMPRulesManager *self, - gconstpointer user_tag, - gboolean all /* or only dirty */) -{ - RulesData * rules_data; - RulesData * rules_data_safe; - RulesUserTagData *user_tag_data; - - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - g_return_if_fail(user_tag); - - if (!self->by_data) - return; - - user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); - if (!user_tag_data) - return; - - c_list_for_each_entry_safe (rules_data, - rules_data_safe, - &user_tag_data->user_tag_lst_head, - user_tag_lst) { - if (all || rules_data->dirty) - _rules_data_untrack(self, rules_data, FALSE, FALSE); - } - if (c_list_is_empty(&user_tag_data->user_tag_lst_head)) - g_hash_table_remove(self->by_user_tag, user_tag_data); -} - -void -nmp_rules_manager_sync(NMPRulesManager *self, gboolean keep_deleted_rules) -{ - const NMDedupMultiHeadEntry *pl_head_entry; - NMDedupMultiIter pl_iter; - const NMPObject * plobj; - gs_unref_ptrarray GPtrArray *rules_to_delete = NULL; - RulesObjData * obj_data; - GHashTableIter h_iter; - guint i; - const RulesData * rd_best; - - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - - if (!self->by_data) - return; - - _LOGD("sync%s", keep_deleted_rules ? " (don't remove any rules)" : ""); - - pl_head_entry = nm_platform_lookup_obj_type(self->platform, NMP_OBJECT_TYPE_ROUTING_RULE); - if (pl_head_entry) { - nmp_cache_iter_for_each (&pl_iter, pl_head_entry, &plobj) { - obj_data = g_hash_table_lookup(self->by_obj, &plobj); - - if (!obj_data) { - /* this rule is not tracked. It was externally added, hence we - * ignore it. */ - continue; - } - - rd_best = _rules_obj_get_best_data(obj_data); - if (rd_best) { - if (rd_best->track_priority_present) { - if (obj_data->config_state == CONFIG_STATE_OWNED_BY_US) - obj_data->config_state = CONFIG_STATE_ADDED_BY_US; - continue; - } - if (rd_best->track_priority_val == 0) { - if (!NM_IN_SET(obj_data->config_state, - CONFIG_STATE_ADDED_BY_US, - CONFIG_STATE_OWNED_BY_US)) { - obj_data->config_state = CONFIG_STATE_NONE; - continue; - } - obj_data->config_state = CONFIG_STATE_NONE; - } - } - - if (keep_deleted_rules) { - _LOGD("forget/leak rule added by us: %s", - nmp_object_to_string(plobj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - continue; - } - - if (!rules_to_delete) - rules_to_delete = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); - - g_ptr_array_add(rules_to_delete, (gpointer) nmp_object_ref(plobj)); - - obj_data->config_state = CONFIG_STATE_REMOVED_BY_US; - } - } - - if (rules_to_delete) { - for (i = 0; i < rules_to_delete->len; i++) - nm_platform_object_delete(self->platform, rules_to_delete->pdata[i]); - } - - g_hash_table_iter_init(&h_iter, self->by_obj); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &obj_data, NULL)) { - rd_best = _rules_obj_get_best_data(obj_data); - - if (!rd_best) { - g_hash_table_iter_remove(&h_iter); - continue; - } - - if (!rd_best->track_priority_present) { - if (obj_data->config_state == CONFIG_STATE_OWNED_BY_US) - obj_data->config_state = CONFIG_STATE_REMOVED_BY_US; - continue; - } - if (rd_best->track_priority_val == 0) { - if (!NM_IN_SET(obj_data->config_state, - CONFIG_STATE_REMOVED_BY_US, - CONFIG_STATE_OWNED_BY_US)) { - obj_data->config_state = CONFIG_STATE_NONE; - continue; - } - obj_data->config_state = CONFIG_STATE_NONE; - } - - plobj = - nm_platform_lookup_obj(self->platform, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj_data->obj); - if (plobj) - continue; - - obj_data->config_state = CONFIG_STATE_ADDED_BY_US; - nm_platform_routing_rule_add(self->platform, - NMP_NLM_FLAG_ADD, - NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj)); - } -} - -void -nmp_rules_manager_track_from_platform(NMPRulesManager *self, - NMPlatform * platform, - int addr_family, - gint32 tracking_priority, - gconstpointer user_tag) -{ - NMPLookup lookup; - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter iter; - const NMPObject * o; - - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - - if (!platform) - platform = self->platform; - else - g_return_if_fail(NM_IS_PLATFORM(platform)); - - nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); - - nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); - head_entry = nm_platform_lookup(platform, &lookup); - nmp_cache_iter_for_each (&iter, head_entry, &o) { - const NMPlatformRoutingRule *rr = NMP_OBJECT_CAST_ROUTING_RULE(o); - - if (addr_family != AF_UNSPEC && rr->addr_family != addr_family) - continue; - - nmp_rules_manager_track(self, rr, tracking_priority, user_tag, NULL); - } -} - -/*****************************************************************************/ - -void -nmp_rules_manager_track_default(NMPRulesManager *self, - int addr_family, - gint32 track_priority, - gconstpointer user_tag) -{ - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - - nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); - - /* track the default rules. See also `man ip-rule`. */ - - if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { - nmp_rules_manager_track(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 0, - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_rules_manager_track(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 32766, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_rules_manager_track(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 32767, - .table = RT_TABLE_DEFAULT, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - } - if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { - nmp_rules_manager_track(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET6, - .priority = 0, - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_rules_manager_track(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET6, - .priority = 32766, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - } -} - -static void -_rules_init(NMPRulesManager *self) -{ - if (self->by_data) - return; - - self->by_data = - g_hash_table_new_full(_rules_data_hash, _rules_data_equal, NULL, _rules_data_destroy); - self->by_obj = - g_hash_table_new_full(_rules_obj_hash, _rules_obj_equal, NULL, _rules_obj_destroy); - self->by_user_tag = g_hash_table_new_full(_rules_user_tag_hash, - _rules_user_tag_equal, - NULL, - _rules_user_tag_destroy); -} - -/*****************************************************************************/ - -NMPRulesManager * -nmp_rules_manager_new(NMPlatform *platform) -{ - NMPRulesManager *self; - - g_return_val_if_fail(NM_IS_PLATFORM(platform), NULL); - - self = g_slice_new(NMPRulesManager); - *self = (NMPRulesManager){ - .ref_count = 1, - .platform = g_object_ref(platform), - }; - return self; -} - -void -nmp_rules_manager_ref(NMPRulesManager *self) -{ - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - - self->ref_count++; -} - -void -nmp_rules_manager_unref(NMPRulesManager *self) -{ - g_return_if_fail(NMP_IS_RULES_MANAGER(self)); - - if (--self->ref_count > 0) - return; - - if (self->by_data) { - g_hash_table_destroy(self->by_user_tag); - g_hash_table_destroy(self->by_obj); - g_hash_table_destroy(self->by_data); - } - g_object_unref(self->platform); - g_slice_free(NMPRulesManager, self); -} diff --git a/src/libnm-platform/nmp-rules-manager.h b/src/libnm-platform/nmp-rules-manager.h deleted file mode 100644 index 69cf9075..00000000 --- a/src/libnm-platform/nmp-rules-manager.h +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#ifndef __NMP_RULES_MANAGER_H__ -#define __NMP_RULES_MANAGER_H__ - -#include "nm-platform.h" - -/*****************************************************************************/ - -#define NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_rules_manager_new) - -typedef struct _NMPRulesManager NMPRulesManager; - -NMPRulesManager *nmp_rules_manager_new(NMPlatform *platform); - -void nmp_rules_manager_ref(NMPRulesManager *self); -void nmp_rules_manager_unref(NMPRulesManager *self); - -#define nm_auto_unref_rules_manager nm_auto(_nmp_rules_manager_unref) -NM_AUTO_DEFINE_FCN0(NMPRulesManager *, _nmp_rules_manager_unref, nmp_rules_manager_unref); - -void nmp_rules_manager_track(NMPRulesManager * self, - const NMPlatformRoutingRule *routing_rule, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack); - -void nmp_rules_manager_track_default(NMPRulesManager *self, - int addr_family, - gint32 track_priority, - gconstpointer user_tag); - -void nmp_rules_manager_track_from_platform(NMPRulesManager *self, - NMPlatform * platform, - int addr_family, - gint32 tracking_priority, - gconstpointer user_tag); - -void nmp_rules_manager_untrack(NMPRulesManager * self, - const NMPlatformRoutingRule *routing_rule, - gconstpointer user_tag); - -void nmp_rules_manager_set_dirty(NMPRulesManager *self, gconstpointer user_tag); - -void nmp_rules_manager_untrack_all(NMPRulesManager *self, - gconstpointer user_tag, - gboolean all /* or only dirty */); - -void nmp_rules_manager_sync(NMPRulesManager *self, gboolean keep_deleted_rules); - -/*****************************************************************************/ - -#endif /* __NMP_RULES_MANAGER_H__ */ diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c index 148657ea..2fa46e38 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c @@ -43,7 +43,7 @@ typedef struct { NMWifiUtils parent; struct nl_sock *nl_sock; - guint32 * freqs; + guint32 *freqs; int id; int num_freqs; int phy; @@ -104,21 +104,21 @@ nl80211_alloc_msg(NMWifiUtilsNl80211 *self, guint32 cmd, guint32 flags) static int nl80211_send_and_recv(NMWifiUtilsNl80211 *self, - struct nl_msg * msg, + struct nl_msg *msg, int (*valid_handler)(struct nl_msg *, void *), void *valid_data) { int err; int done = 0; const struct nl_cb cb = { - .err_cb = error_handler, - .err_arg = &done, - .finish_cb = finish_handler, - .finish_arg = &done, - .ack_cb = ack_handler, - .ack_arg = &done, - .valid_cb = valid_handler, - .valid_arg = valid_data, + .err_cb = error_handler, + .err_arg = &done, + .finish_cb = finish_handler, + .finish_arg = &done, + .ack_cb = ack_handler, + .ack_arg = &done, + .valid_cb = valid_handler, + .valid_arg = valid_data, }; g_return_val_if_fail(msg != NULL, -ENOMEM); @@ -169,8 +169,8 @@ static int nl80211_iface_info_handler(struct nl_msg *msg, void *arg) { struct nl80211_iface_info *info = arg; - struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct nlattr * tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0) return NL_SKIP; @@ -202,7 +202,7 @@ nl80211_iface_info_handler(struct nl_msg *msg, void *arg) static _NM80211Mode wifi_nl80211_get_mode(NMWifiUtils *data) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_iface_info iface_info = { .mode = _NM_802_11_MODE_UNKNOWN, }; @@ -219,7 +219,7 @@ wifi_nl80211_get_mode(NMWifiUtils *data) static gboolean wifi_nl80211_set_mode(NMWifiUtils *data, const _NM80211Mode mode) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -252,7 +252,7 @@ nla_put_failure: static gboolean wifi_nl80211_set_powersave(NMWifiUtils *data, guint32 powersave) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -271,9 +271,9 @@ static int nl80211_get_wake_on_wlan_handler(struct nl_msg *msg, void *arg) { _NMSettingWirelessWakeOnWLan *wowl = arg; - struct nlattr * attrs[NL80211_ATTR_MAX + 1]; - struct nlattr * trig[NUM_NL80211_WOWLAN_TRIG]; - struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); nla_parse_arr(attrs, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); @@ -309,7 +309,7 @@ nl80211_get_wake_on_wlan_handler(struct nl_msg *msg, void *arg) static _NMSettingWirelessWakeOnWLan wifi_nl80211_get_wake_on_wlan(NMWifiUtils *data) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; _NMSettingWirelessWakeOnWLan wowl = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -323,9 +323,9 @@ wifi_nl80211_get_wake_on_wlan(NMWifiUtils *data) static gboolean wifi_nl80211_set_wake_on_wlan(NMWifiUtils *data, _NMSettingWirelessWakeOnWLan wowl) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; - struct nlattr * triggers; + struct nlattr *triggers; int err; if (wowl == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) @@ -365,7 +365,7 @@ nla_put_failure: static guint32 wifi_nl80211_get_freq(NMWifiUtils *data) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_iface_info iface_info = {}; nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -441,11 +441,11 @@ nl80211_station_dump_handler(struct nl_msg *msg, void *arg) [NL80211_RATE_INFO_40_MHZ_WIDTH] = {.type = NLA_FLAG}, [NL80211_RATE_INFO_SHORT_GI] = {.type = NLA_FLAG}, }; - struct nlattr * rinfo[G_N_ELEMENTS(rate_policy)]; - struct nlattr * sinfo[G_N_ELEMENTS(stats_policy)]; + struct nlattr *rinfo[G_N_ELEMENTS(rate_policy)]; + struct nlattr *sinfo[G_N_ELEMENTS(stats_policy)]; struct nl80211_station_info *info = arg; - struct nlattr * tb[NL80211_ATTR_MAX + 1]; - struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0) return NL_SKIP; @@ -495,10 +495,10 @@ nl80211_station_dump_handler(struct nl_msg *msg, void *arg) static gboolean wifi_nl80211_get_station(NMWifiUtils *data, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate) + int *out_quality, + guint32 *out_rate) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nl80211_station_info sta_info = {}; @@ -525,7 +525,7 @@ wifi_nl80211_get_station(NMWifiUtils *data, static gboolean wifi_nl80211_indicate_addressing_running(NMWifiUtils *data, gboolean running) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -552,7 +552,7 @@ nla_put_failure: struct nl80211_device_info { NMWifiUtilsNl80211 *self; int phy; - guint32 * freqs; + guint32 *freqs; int num_freqs; guint32 freq; guint32 caps; @@ -587,14 +587,14 @@ nl80211_wiphy_info_handler(struct nl_msg *msg, void *arg) [NL80211_FREQUENCY_ATTR_RADAR] = {.type = NLA_FLAG}, [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = {.type = NLA_U32}, }; - struct nlattr * tb[NL80211_ATTR_MAX + 1]; - struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nl80211_device_info *info = arg; - NMWifiUtilsNl80211 * self = info->self; - struct nlattr * tb_band[NL80211_BAND_ATTR_MAX + 1]; - struct nlattr * tb_freq[G_N_ELEMENTS(freq_policy)]; - struct nlattr * nl_band; - struct nlattr * nl_freq; + NMWifiUtilsNl80211 *self = info->self; + struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; + struct nlattr *tb_freq[G_N_ELEMENTS(freq_policy)]; + struct nlattr *nl_band; + struct nlattr *nl_freq; int rem_freq; int rem_band; int freq_idx; @@ -761,7 +761,7 @@ nl80211_wiphy_info_handler(struct nl_msg *msg, void *arg) static guint32 wifi_nl80211_get_mesh_channel(NMWifiUtils *data) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nl80211_device_info device_info = {.self = self}; int i; @@ -783,7 +783,7 @@ wifi_nl80211_get_mesh_channel(NMWifiUtils *data) static gboolean wifi_nl80211_set_mesh_channel(NMWifiUtils *data, guint32 channel) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -802,7 +802,7 @@ nla_put_failure: static gboolean wifi_nl80211_set_mesh_ssid(NMWifiUtils *data, const guint8 *ssid, gsize len) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -822,7 +822,7 @@ nm_wifi_utils_nl80211_init(NMWifiUtilsNl80211 *self) static void nm_wifi_utils_nl80211_class_init(NMWifiUtilsNl80211Class *klass) { - GObjectClass * object_class = G_OBJECT_CLASS(klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS(klass); object_class->dispose = dispose; @@ -845,7 +845,7 @@ NMWifiUtils * nm_wifi_utils_nl80211_new(int ifindex, struct nl_sock *genl) { gs_unref_object NMWifiUtilsNl80211 *self = NULL; - nm_auto_nlmsg struct nl_msg * msg = NULL; + nm_auto_nlmsg struct nl_msg *msg = NULL; struct nl80211_device_info device_info = {}; if (!genl) diff --git a/src/libnm-platform/wifi/nm-wifi-utils-private.h b/src/libnm-platform/wifi/nm-wifi-utils-private.h index bc1e75ec..7461b65e 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-private.h +++ b/src/libnm-platform/wifi/nm-wifi-utils-private.h @@ -39,8 +39,8 @@ typedef struct { */ gboolean (*get_station)(NMWifiUtils *data, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate); + int *out_quality, + guint32 *out_rate); /* OLPC Mesh-only functions */ diff --git a/src/libnm-platform/wifi/nm-wifi-utils-wext.c b/src/libnm-platform/wifi/nm-wifi-utils-wext.c index 6fb37c49..2d4112bc 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-wext.c +++ b/src/libnm-platform/wifi/nm-wifi-utils-wext.c @@ -427,7 +427,7 @@ wext_qual_to_percent(const struct iw_quality *qual, const struct iw_quality *max static int wifi_wext_get_qual(NMWifiUtils *data) { - NMWifiUtilsWext * wext = (NMWifiUtilsWext *) data; + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; struct iwreq wrq; struct iw_statistics stats; char ifname[IFNAMSIZ]; @@ -455,8 +455,8 @@ wifi_wext_get_qual(NMWifiUtils *data) static gboolean wifi_wext_get_station(NMWifiUtils *data, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate) + int *out_quality, + guint32 *out_rate) { NMEtherAddr local_addr; @@ -588,9 +588,9 @@ wext_can_scan_ifname(NMWifiUtilsWext *wext, const char *ifname) static gboolean wext_get_range_ifname(NMWifiUtilsWext *wext, - const char * ifname, + const char *ifname, struct iw_range *range, - guint32 * response_len) + guint32 *response_len) { int i = 26; gboolean success = FALSE; @@ -698,7 +698,7 @@ nm_wifi_utils_wext_init(NMWifiUtilsWext *self) static void nm_wifi_utils_wext_class_init(NMWifiUtilsWextClass *klass) { - GObjectClass * object_class = G_OBJECT_CLASS(klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS(klass); object_class->dispose = dispose; @@ -717,7 +717,7 @@ nm_wifi_utils_wext_class_init(NMWifiUtilsWextClass *klass) NMWifiUtils * nm_wifi_utils_wext_new(int ifindex, gboolean check_scan) { - NMWifiUtilsWext * wext; + NMWifiUtilsWext *wext; struct iw_range range; guint32 response_len = 0; struct iw_range_with_scan_capa *scan_capa_range; diff --git a/src/libnm-platform/wifi/nm-wifi-utils.c b/src/libnm-platform/wifi/nm-wifi-utils.c index 0b5f8d71..8bdd65c2 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils.c +++ b/src/libnm-platform/wifi/nm-wifi-utils.c @@ -132,8 +132,8 @@ nm_wifi_utils_find_freq(NMWifiUtils *data, const guint32 *freqs) gboolean nm_wifi_utils_get_station(NMWifiUtils *data, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate) + int *out_quality, + guint32 *out_rate) { g_return_val_if_fail(data != NULL, FALSE); diff --git a/src/libnm-platform/wifi/nm-wifi-utils.h b/src/libnm-platform/wifi/nm-wifi-utils.h index 157522ee..be33b90c 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils.h +++ b/src/libnm-platform/wifi/nm-wifi-utils.h @@ -51,8 +51,8 @@ guint32 nm_wifi_utils_find_freq(NMWifiUtils *data, const guint32 *freqs); */ gboolean nm_wifi_utils_get_station(NMWifiUtils *data, NMEtherAddr *out_bssid, - int * out_quality, - guint32 * out_rate); + int *out_quality, + guint32 *out_rate); /* Tells the driver DHCP or SLAAC is running */ gboolean nm_wifi_utils_indicate_addressing_running(NMWifiUtils *data, gboolean running); diff --git a/src/libnm-platform/wpan/nm-wpan-utils.c b/src/libnm-platform/wpan/nm-wpan-utils.c index 082cc3e7..d9bbd0f0 100644 --- a/src/libnm-platform/wpan/nm-wpan-utils.c +++ b/src/libnm-platform/wpan/nm-wpan-utils.c @@ -95,7 +95,7 @@ nl802154_alloc_msg(NMWpanUtils *self, guint32 cmd, guint32 flags) } static int -nl802154_send_and_recv(NMWpanUtils * self, +nl802154_send_and_recv(NMWpanUtils *self, struct nl_msg *msg, int (*valid_handler)(struct nl_msg *, void *), void *valid_data) @@ -103,14 +103,14 @@ nl802154_send_and_recv(NMWpanUtils * self, int err; int done = 0; const struct nl_cb cb = { - .err_cb = error_handler, - .err_arg = &done, - .finish_cb = finish_handler, - .finish_arg = &done, - .ack_cb = ack_handler, - .ack_arg = &done, - .valid_cb = valid_handler, - .valid_arg = valid_data, + .err_cb = error_handler, + .err_arg = &done, + .finish_cb = finish_handler, + .finish_arg = &done, + .ack_cb = ack_handler, + .ack_arg = &done, + .valid_cb = valid_handler, + .valid_arg = valid_data, }; g_return_val_if_fail(msg != NULL, -ENOMEM); @@ -149,9 +149,9 @@ nl802154_get_interface_handler(struct nl_msg *msg, void *arg) [NL802154_ATTR_PAN_ID] = {.type = NLA_U16}, [NL802154_ATTR_SHORT_ADDR] = {.type = NLA_U16}, }; - struct nlattr * tb[G_N_ELEMENTS(nl802154_policy)]; + struct nlattr *tb[G_N_ELEMENTS(nl802154_policy)]; struct nl802154_interface *info = arg; - struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), nl802154_policy) < 0) return NL_SKIP; |