File: netaddrq.h

package info (click to toggle)
util-linux 2.42~rc1-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 101,864 kB
  • sloc: ansic: 185,733; sh: 24,450; yacc: 1,288; makefile: 534; xml: 422; python: 316; lex: 89; ruby: 75; csh: 37; exp: 19; sed: 16; perl: 15; sql: 9
file content (130 lines) | stat: -rw-r--r-- 4,781 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Netlink address quality rating list builder
 *
 * Copyright (C) 2025 Stanislav Brabec <sbrabec@suse.com>
 *
 * This program is freely distributable.
 *
 * This set of netlink callbacks kernel and creates
 * and/or maintains a linked list of requested type. Using callback functions
 * and custom data, it could be used for arbitrary purpose.
 *
 */

#ifndef UTIL_LINUX_NETADDRQ_H
#define UTIL_LINUX_NETADDRQ_H

#include "netlink.h"

/* Specific return code */
#define	UL_NL_IFACES_MAX	 64	/* ADDR: Too many interfaces */

/* Network address "quality". Higher means worse. */
enum ul_netaddrq_ip_rating {
	ULNETLINK_RATING_SCOPE_UNIVERSE,
	ULNETLINK_RATING_SCOPE_SITE,
	ULNETLINK_RATING_F_TEMPORARY,
	ULNETLINK_RATING_SCOPE_LINK,
	ULNETLINK_RATING_BAD,
	__ULNETLINK_RATING_MAX
};

/* Data structure in ul_nl_data You can use callback_pre for filtering events
 * you want to get into the list, callback_post to check the processed data or
 * use the list after processing
 */
struct ul_netaddrq_data {
	ul_nl_callback callback_pre;  /* Function to process ul_netaddrq_data */
	ul_nl_callback callback_post; /* Function to process ul_netaddrq_data */
	void *callback_data;	      /* Arbitrary data for callback */
	struct list_head ifaces;      /* The interfaces list */
	/* ifaces_change_* has to be changed by userspace when processed. */
	bool ifaces_change_4;	      /* Any changes in the IPv4 list? */
	bool ifaces_change_6;	      /* Any changes in the IPv6 list? */
	int nifaces;		      /* interface count */
	bool overflow;		      /* Too many interfaces? */
};

/* List item for particular interface contains interface specific data and
 * heads of two lists, one per each address family */
struct ul_netaddrq_iface {
	struct list_head entry;
	uint32_t ifa_index;
	char *ifname;
	struct list_head ip_quality_list_4;
	struct list_head ip_quality_list_6;
};

/* Macro casting generic ul_nl_data->data_addr to struct ul_netaddrq_data */
#define UL_NETADDRQ_DATA(nl) ((struct ul_netaddrq_data*)((nl)->data_addr))

/* list_for_each macro for intercaces */
#define list_for_each_netaddrq_iface(li, nl) list_for_each(li, &(UL_NETADDRQ_DATA(nl)->ifaces))

/* List item for for a particular address contains information for IP quality
 * evaluation and a copy of generic ul_nl_addr data */
struct ul_netaddrq_ip {
	struct list_head entry;
	enum ul_netaddrq_ip_rating quality;
	struct ul_nl_addr *addr;
};

/* Initialize ul_nl_data for use with netlink-addr-quality
 * callback: Process the data after updating the tree. If NULL, it just
 *   updates the tree and everything has to be processed outside.
 */
int ul_netaddrq_init(struct ul_nl_data *nl, ul_nl_callback callback_pre,
		     ul_nl_callback callback_post, void *data);

/* Get best rating value from the ul_netaddrq_ip list
 * ipq_list: List of IP addresses of a particular interface and family
 * returns:
 *   best array: best ifa_valid lifetime seen per quality rating
 *   return value: best rating seen
 * Note: It can be needed to call it twice: once for ip_quality_list_4, once
 * for ip_quality_list_6.
 */
enum ul_netaddrq_ip_rating
ul_netaddrq_iface_bestaddr(struct list_head *ipq_list,
			   struct ul_netaddrq_ip *(*best)[__ULNETLINK_RATING_MAX]);

/* Get best rating value from the ifaces list (i. e. best address of all
 * interfaces)
 * returns:
 *   best_iface: interface where the best address was seen
 *   best array: best ifa_valid lifetime seen per quality rating
 *   return value: best rating seen
 * Notes:
 * - It can be needed to call it twice: once for ip_quality_list_4, once
 *   for ip_quality_list_6.
 * - If no IP addresses are found, the function can return
 *   _ULNETLINK_RATING_MAX!
 */
enum ul_netaddrq_ip_rating
ul_netaddrq_bestaddr(struct ul_nl_data *nl,
		     struct ul_netaddrq_iface **best_iface,
		     struct ul_netaddrq_ip *(*best)[__ULNETLINK_RATING_MAX],
		     uint8_t ifa_family);

/* Get best rating value from the ul_netaddrq_ip list as a string
 * ipq_list: List of IP addresses of a particular interface and family
 * returns:
 *   return value: The best address as a string
 *   threshold: The best rating ever seen.
 *   best_ifaceq: The best rated interfece ever seen.
 * Notes:
 * - It can be needed to call it twice: once for AF_INET, once
 *   for AF_INET6.
 * - If the return value is NULL (i. e. there are no usable interfaces), then
 *   *best_ifaceq remains unchanges and cannot be used.
 */
const char *ul_netaddrq_get_best_ipp(struct ul_nl_data *nl,
				     uint8_t ifa_family,
				     enum ul_netaddrq_ip_rating *threshold,
				     struct ul_netaddrq_iface **best_ifaceq);

/* Find interface by name */
struct ul_netaddrq_iface *ul_netaddrq_iface_by_name(const struct ul_nl_data *nl,
						    const char *ifname);

#endif /* UTIL_LINUX_NETADDRQ_H */