Merge branch 'main' into next

Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
David Ahern 2020-12-04 16:25:12 +00:00
commit 8065d28218
8 changed files with 63 additions and 21 deletions

View File

@ -2744,7 +2744,7 @@ static int cmd_dev_param_set(struct dl *dl)
struct param_ctx ctx = {}; struct param_ctx ctx = {};
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
bool conv_exists; bool conv_exists;
uint32_t val_u32; uint32_t val_u32 = 0;
uint16_t val_u16; uint16_t val_u16;
uint8_t val_u8; uint8_t val_u8;
bool val_bool; bool val_bool;

View File

@ -74,7 +74,7 @@ static void explain(void)
void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len) void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
{ {
char eaddr[32]; char eaddr[18];
ether_ntoa_r((const struct ether_addr *)id->addr, eaddr); ether_ntoa_r((const struct ether_addr *)id->addr, eaddr);
snprintf(buf, len, "%.2x%.2x.%s", id->prio[0], id->prio[1], eaddr); snprintf(buf, len, "%.2x%.2x.%s", id->prio[0], id->prio[1], eaddr);

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#define _ATFILE_SOURCE #define _ATFILE_SOURCE
#include <sys/file.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -801,6 +802,7 @@ static int netns_add(int argc, char **argv, bool create)
const char *name; const char *name;
pid_t pid; pid_t pid;
int fd; int fd;
int lock;
int made_netns_run_dir_mount = 0; int made_netns_run_dir_mount = 0;
if (create) { if (create) {
@ -831,12 +833,37 @@ static int netns_add(int argc, char **argv, bool create)
* namespace file in one namespace will unmount the network namespace * namespace file in one namespace will unmount the network namespace
* file in all namespaces allowing the network namespace to be freed * file in all namespaces allowing the network namespace to be freed
* sooner. * sooner.
* These setup steps need to happen only once, as if multiple ip processes
* try to attempt the same operation at the same time, the mountpoints will
* be recursively created multiple times, eventually causing the system
* to lock up. For example, this has been observed when multiple netns
* namespaces are created in parallel at boot. See:
* https://bugs.debian.org/949235
* Try to take an exclusive file lock on the top level directory to ensure
* this cannot happen, but proceed nonetheless if it cannot happen for any
* reason.
*/ */
lock = open(NETNS_RUN_DIR, O_RDONLY|O_DIRECTORY, 0);
if (lock < 0) {
fprintf(stderr, "Cannot open netns runtime directory \"%s\": %s\n",
NETNS_RUN_DIR, strerror(errno));
return -1;
}
if (flock(lock, LOCK_EX) < 0) {
fprintf(stderr, "Warning: could not flock netns runtime directory \"%s\": %s\n",
NETNS_RUN_DIR, strerror(errno));
close(lock);
lock = -1;
}
while (mount("", NETNS_RUN_DIR, "none", MS_SHARED | MS_REC, NULL)) { while (mount("", NETNS_RUN_DIR, "none", MS_SHARED | MS_REC, NULL)) {
/* Fail unless we need to make the mount point */ /* Fail unless we need to make the mount point */
if (errno != EINVAL || made_netns_run_dir_mount) { if (errno != EINVAL || made_netns_run_dir_mount) {
fprintf(stderr, "mount --make-shared %s failed: %s\n", fprintf(stderr, "mount --make-shared %s failed: %s\n",
NETNS_RUN_DIR, strerror(errno)); NETNS_RUN_DIR, strerror(errno));
if (lock != -1) {
flock(lock, LOCK_UN);
close(lock);
}
return -1; return -1;
} }
@ -844,10 +871,18 @@ static int netns_add(int argc, char **argv, bool create)
if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND | MS_REC, NULL)) { if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND | MS_REC, NULL)) {
fprintf(stderr, "mount --bind %s %s failed: %s\n", fprintf(stderr, "mount --bind %s %s failed: %s\n",
NETNS_RUN_DIR, NETNS_RUN_DIR, strerror(errno)); NETNS_RUN_DIR, NETNS_RUN_DIR, strerror(errno));
if (lock != -1) {
flock(lock, LOCK_UN);
close(lock);
}
return -1; return -1;
} }
made_netns_run_dir_mount = 1; made_netns_run_dir_mount = 1;
} }
if (lock != -1) {
flock(lock, LOCK_UN);
close(lock);
}
/* Create the filesystem state */ /* Create the filesystem state */
fd = open(netns_path, O_RDONLY|O_CREAT|O_EXCL, 0); fd = open(netns_path, O_RDONLY|O_CREAT|O_EXCL, 0);

View File

@ -251,7 +251,7 @@ static void load_raw_table(FILE *fp)
buf[strlen(buf)-1] = 0; buf[strlen(buf)-1] = 0;
if (info_source[0] && strcmp(info_source, buf+1)) if (info_source[0] && strcmp(info_source, buf+1))
source_mismatch = 1; source_mismatch = 1;
strncpy(info_source, buf+1, sizeof(info_source)-1); strlcpy(info_source, buf+1, sizeof(info_source));
continue; continue;
} }
if ((n = malloc(sizeof(*n))) == NULL) if ((n = malloc(sizeof(*n))) == NULL)

View File

@ -136,8 +136,7 @@ static void load_good_table(FILE *fp)
buf[strlen(buf)-1] = 0; buf[strlen(buf)-1] = 0;
if (info_source[0] && strcmp(info_source, buf+1)) if (info_source[0] && strcmp(info_source, buf+1))
source_mismatch = 1; source_mismatch = 1;
info_source[0] = 0; strlcpy(info_source, buf + 1, sizeof(info_source));
strncat(info_source, buf+1, sizeof(info_source)-1);
continue; continue;
} }
/* idbuf is as big as buf, so this is safe */ /* idbuf is as big as buf, so this is safe */

View File

@ -1110,7 +1110,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
} }
NEXT_ARG(); NEXT_ARG();
} }
hash = sel2.sel.keys[0].val & sel2.sel.keys[0].mask; hash = sel2.keys[0].val & sel2.keys[0].mask;
hash ^= hash >> 16; hash ^= hash >> 16;
hash ^= hash >> 8; hash ^= hash >> 8;
htid = ((hash % divisor) << 12) | (htid & 0xFFF00000); htid = ((hash % divisor) << 12) | (htid & 0xFFF00000);

View File

@ -82,7 +82,7 @@ parse_ip6(int *argc_p, char ***argv_p,
/* Shift the field by 4 bits on success. */ /* Shift the field by 4 bits on success. */
if (!res) { if (!res) {
int nkeys = sel->sel.nkeys; int nkeys = sel->sel.nkeys;
struct tc_pedit_key *key = &sel->sel.keys[nkeys - 1]; struct tc_pedit_key *key = &sel->keys[nkeys - 1];
key->mask = htonl(ntohl(key->mask) << 4 | 0xf); key->mask = htonl(ntohl(key->mask) << 4 | 0xf);
key->val = htonl(ntohl(key->val) << 4); key->val = htonl(ntohl(key->val) << 4);

View File

@ -243,13 +243,19 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
qopt = RTA_DATA(opt); qopt = RTA_DATA(opt);
fprintf(f, " tc %u map ", qopt->num_tc); print_uint(PRINT_ANY, "tc", "tc %u ", qopt->num_tc);
open_json_array(PRINT_ANY, is_json_context() ? "map" : "map ");
for (i = 0; i <= TC_PRIO_MAX; i++) for (i = 0; i <= TC_PRIO_MAX; i++)
fprintf(f, "%u ", qopt->prio_tc_map[i]); print_uint(PRINT_ANY, NULL, "%u ", qopt->prio_tc_map[i]);
fprintf(f, "\n queues:"); close_json_array(PRINT_ANY, "");
for (i = 0; i < qopt->num_tc; i++) open_json_array(PRINT_ANY, is_json_context() ? "queues" : "\n queues:");
fprintf(f, "(%u:%u) ", qopt->offset[i], for (i = 0; i < qopt->num_tc; i++) {
qopt->offset[i] + qopt->count[i] - 1); open_json_array(PRINT_JSON, NULL);
print_uint(PRINT_ANY, NULL, "(%u:", qopt->offset[i]);
print_uint(PRINT_ANY, NULL, "%u) ", qopt->offset[i] + qopt->count[i] - 1);
close_json_array(PRINT_JSON, NULL);
}
close_json_array(PRINT_ANY, "");
if (len > 0) { if (len > 0) {
struct rtattr *tb[TCA_MQPRIO_MAX + 1]; struct rtattr *tb[TCA_MQPRIO_MAX + 1];
@ -262,18 +268,18 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
__u16 *mode = RTA_DATA(tb[TCA_MQPRIO_MODE]); __u16 *mode = RTA_DATA(tb[TCA_MQPRIO_MODE]);
if (*mode == TC_MQPRIO_MODE_CHANNEL) if (*mode == TC_MQPRIO_MODE_CHANNEL)
fprintf(f, "\n mode:channel"); print_string(PRINT_ANY, "mode", "\n mode:%s", "channel");
} else { } else {
fprintf(f, "\n mode:dcb"); print_string(PRINT_ANY, "mode", "\n mode:%s", "dcb");
} }
if (tb[TCA_MQPRIO_SHAPER]) { if (tb[TCA_MQPRIO_SHAPER]) {
__u16 *shaper = RTA_DATA(tb[TCA_MQPRIO_SHAPER]); __u16 *shaper = RTA_DATA(tb[TCA_MQPRIO_SHAPER]);
if (*shaper == TC_MQPRIO_SHAPER_BW_RATE) if (*shaper == TC_MQPRIO_SHAPER_BW_RATE)
fprintf(f, "\n shaper:bw_rlimit"); print_string(PRINT_ANY, "shaper", "\n shaper:%s", "bw_rlimit");
} else { } else {
fprintf(f, "\n shaper:dcb"); print_string(PRINT_ANY, "shaper", "\n shaper:%s", "dcb");
} }
if (tb[TCA_MQPRIO_MIN_RATE64]) { if (tb[TCA_MQPRIO_MIN_RATE64]) {
@ -287,9 +293,10 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
return -1; return -1;
*(min++) = rta_getattr_u64(r); *(min++) = rta_getattr_u64(r);
} }
fprintf(f, " min_rate:"); open_json_array(PRINT_ANY, is_json_context() ? "min_rate" : " min_rate:");
for (i = 0; i < qopt->num_tc; i++) for (i = 0; i < qopt->num_tc; i++)
fprintf(f, "%s ", sprint_rate(min_rate64[i], b1)); print_string(PRINT_ANY, NULL, "%s ", sprint_rate(min_rate64[i], b1));
close_json_array(PRINT_ANY, "");
} }
if (tb[TCA_MQPRIO_MAX_RATE64]) { if (tb[TCA_MQPRIO_MAX_RATE64]) {
@ -303,9 +310,10 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
return -1; return -1;
*(max++) = rta_getattr_u64(r); *(max++) = rta_getattr_u64(r);
} }
fprintf(f, " max_rate:"); open_json_array(PRINT_ANY, is_json_context() ? "max_rate" : " max_rate:");
for (i = 0; i < qopt->num_tc; i++) for (i = 0; i < qopt->num_tc; i++)
fprintf(f, "%s ", sprint_rate(max_rate64[i], b1)); print_string(PRINT_ANY, NULL, "%s ", sprint_rate(max_rate64[i], b1));
close_json_array(PRINT_ANY, "");
} }
} }
return 0; return 0;