networkd: rework how carrier bindings are serialized

Instead of serializing the interface name, expose the interface index, since
that's the only stable identifier.
This commit is contained in:
Lennart Poettering 2016-02-19 20:43:03 +01:00
parent 7cececb2ea
commit b295beea88
4 changed files with 117 additions and 38 deletions

View File

@ -207,12 +207,66 @@ _public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "ROUTE_DOMAINS", ret);
}
_public_ int sd_network_link_get_carrier_bound_to(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "CARRIER_BOUND_TO", ret);
static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
_cleanup_free_ char *p = NULL, *s = NULL;
_cleanup_strv_free_ char **a = NULL;
_cleanup_free_ int *ifis = NULL;
size_t allocated = 0, c = 0;
const char *x;
int r;
assert_return(ifindex > 0, -EINVAL);
assert_return(ret, -EINVAL);
if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
return -ENOMEM;
r = parse_env_file(p, NEWLINE, key, &s, NULL);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
return r;
if (isempty(s)) {
*ret = NULL;
return 0;
}
x = s;
for (;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&x, &word, NULL, 0);
if (r < 0)
return r;
if (r == 0)
break;
r = parse_ifindex(word, &ifindex);
if (r < 0)
return r;
if (!GREEDY_REALLOC(ifis, allocated, c + 1))
return -ENOMEM;
ifis[c++] = ifindex;
}
if (!GREEDY_REALLOC(ifis, allocated, c + 1))
return -ENOMEM;
ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice*/
*ret = ifis;
ifis = NULL;
return c;
}
_public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "CARRIER_BOUND_BY", ret);
_public_ int sd_network_link_get_carrier_bound_to(int ifindex, int **ret) {
return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_TO", ret);
}
_public_ int sd_network_link_get_carrier_bound_by(int ifindex, int **ret) {
return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_BY", ret);
}
static inline int MONITOR_TO_FD(sd_network_monitor *m) {

View File

@ -662,6 +662,30 @@ static int dump_lldp_neighbors(const char *prefix, int ifindex) {
return c;
}
static void dump_ifindexes(const char *prefix, const int *ifindexes) {
unsigned c;
assert(prefix);
if (!ifindexes || ifindexes[0] <= 0)
return;
for (c = 0; ifindexes[c] > 0; c++) {
char name[IF_NAMESIZE+1];
printf("%*s",
(int) strlen(prefix),
c == 0 ? prefix : "");
if (if_indextoname(ifindexes[c], name))
fputs(name, stdout);
else
printf("%i", ifindexes[c]);
fputc('\n', stdout);
}
}
static void dump_list(const char *prefix, char **l) {
char **i;
@ -689,8 +713,7 @@ static int link_status_one(
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
const char *on_color_operational, *off_color_operational,
*on_color_setup, *off_color_setup;
_cleanup_strv_free_ char **carrier_bound_to = NULL;
_cleanup_strv_free_ char **carrier_bound_by = NULL;
_cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
int r;
assert(rtnl);
@ -777,8 +800,8 @@ static int link_status_one(
dump_list(" NTP: ", ntp);
dump_list("Carrier Bound To: ", carrier_bound_to);
dump_list("Carrier Bound By: ", carrier_bound_by);
dump_ifindexes("Carrier Bound To: ", carrier_bound_to);
dump_ifindexes("Carrier Bound By: ", carrier_bound_by);
(void) sd_network_link_get_timezone(info->ifindex, &tz);
if (tz)

View File

@ -1622,7 +1622,7 @@ static int link_new_bound_by_list(Link *link) {
m = link->manager;
HASHMAP_FOREACH (carrier, m->links, i) {
HASHMAP_FOREACH(carrier, m->links, i) {
if (!carrier->network)
continue;
@ -1641,7 +1641,7 @@ static int link_new_bound_by_list(Link *link) {
if (list_updated)
link_dirty(link);
HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
r = link_put_carrier(carrier, link, &carrier->bound_to_links);
if (r < 0)
return r;
@ -2631,7 +2631,6 @@ int link_carrier_reset(Link *link) {
return 0;
}
int link_update(Link *link, sd_netlink_message *m) {
struct ether_addr mac;
const char *ifname;
@ -2752,12 +2751,34 @@ int link_update(Link *link, sd_netlink_message *m) {
r = link_carrier_lost(link);
if (r < 0)
return r;
}
return 0;
}
static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
bool space = false;
Iterator i;
Link *link;
assert(f);
assert(prefix);
if (hashmap_isempty(h))
return;
fputs(prefix, f);
HASHMAP_FOREACH(link, h, i) {
if (space)
fputc(' ', f);
fprintf(f, "%i", link->ifindex);
space = true;
}
fputc('\n', f);
}
int link_save(Link *link) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
@ -2958,27 +2979,8 @@ int link_save(Link *link) {
fputc('\n', f);
}
if (!hashmap_isempty(link->bound_to_links)) {
Link *carrier;
bool space = false;
fputs("CARRIER_BOUND_TO=", f);
HASHMAP_FOREACH(carrier, link->bound_to_links, i)
fputs_with_space(f, carrier->ifname, NULL, &space);
fputc('\n', f);
}
if (!hashmap_isempty(link->bound_by_links)) {
Link *carrier;
bool space = false;
fputs("CARRIER_BOUND_BY=", f);
HASHMAP_FOREACH(carrier, link->bound_by_links, i)
fputs_with_space(f, carrier->ifname, NULL, &space);
fputc('\n', f);
}
print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
if (link->dhcp_lease) {
struct in_addr address;

View File

@ -99,11 +99,11 @@ int sd_network_link_get_network_file(int ifindex, char **filename);
/* Get DNS entries for a given link. These are string representations of
* IP addresses */
int sd_network_link_get_dns(int ifindex, char ***addr);
int sd_network_link_get_dns(int ifindex, char ***ret);
/* Get NTP entries for a given link. These are domain names or string
* representations of IP addresses */
int sd_network_link_get_ntp(int ifindex, char ***addr);
int sd_network_link_get_ntp(int ifindex, char ***ret);
/* Indicates whether or not LLMNR should be enabled for the link
* Possible levels of support: yes, no, resolve
@ -139,11 +139,11 @@ int sd_network_link_get_search_domains(int ifindex, char ***domains);
/* Get the route DNS domain names for a given link. */
int sd_network_link_get_route_domains(int ifindex, char ***domains);
/* Get the CARRIERS to which current link is bound to. */
int sd_network_link_get_carrier_bound_to(int ifindex, char ***carriers);
/* Get the carrier interface indexes to which current link is bound to. */
int sd_network_link_get_carrier_bound_to(int ifindex, int **ifindexes);
/* Get the CARRIERS that are bound to current link. */
int sd_network_link_get_carrier_bound_by(int ifindex, char ***carriers);
int sd_network_link_get_carrier_bound_by(int ifindex, int **ifindexes);
/* Get the timezone that was learnt on a specific link. */
int sd_network_link_get_timezone(int ifindex, char **timezone);