diff --git a/etc/iproute2/rt_tables.d/README b/etc/iproute2/rt_tables.d/README new file mode 100644 index 00000000..79386f89 --- /dev/null +++ b/etc/iproute2/rt_tables.d/README @@ -0,0 +1,3 @@ +Each file in this directory is an rt_tables configuration file. iproute2 +commands scan this directory processing all files that end in '.conf'. + diff --git a/include/libnetlink.h b/include/libnetlink.h index 2280c39c..431189e2 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -60,11 +60,16 @@ struct rtnl_dump_filter_arg { rtnl_filter_t filter; void *arg1; + __u16 nc_flags; }; int rtnl_dump_filter_l(struct rtnl_handle *rth, const struct rtnl_dump_filter_arg *arg); -int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, void *arg); +int rtnl_dump_filter_nc(struct rtnl_handle *rth, + rtnl_filter_t filter, + void *arg, __u16 nc_flags); +#define rtnl_dump_filter(rth, filter, arg) \ + rtnl_dump_filter_nc(rth, filter, arg, 0) int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, struct nlmsghdr *answer, size_t len) __attribute__((warn_unused_result)); diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 05358c97..bc8359eb 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -1148,28 +1148,6 @@ brief_exit: return 0; } -static int print_addrinfo_primary(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - struct ifaddrmsg *ifa = NLMSG_DATA(n); - - if (ifa->ifa_flags & IFA_F_SECONDARY) - return 0; - - return print_addrinfo(who, n, arg); -} - -static int print_addrinfo_secondary(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - struct ifaddrmsg *ifa = NLMSG_DATA(n); - - if (!(ifa->ifa_flags & IFA_F_SECONDARY)) - return 0; - - return print_addrinfo(who, n, arg); -} - struct nlmsg_list { struct nlmsg_list *next; @@ -1420,26 +1398,13 @@ static int ipaddr_flush(void) filter.flushe = sizeof(flushb); while ((max_flush_loops == 0) || (round < max_flush_loops)) { - const struct rtnl_dump_filter_arg a[3] = { - { - .filter = print_addrinfo_secondary, - .arg1 = stdout, - }, - { - .filter = print_addrinfo_primary, - .arg1 = stdout, - }, - { - .filter = NULL, - .arg1 = NULL, - }, - }; if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { perror("Cannot send dump request"); exit(1); } filter.flushed = 0; - if (rtnl_dump_filter_l(&rth, a) < 0) { + if (rtnl_dump_filter_nc(&rth, print_addrinfo, + stdout, NLM_F_DUMP_INTR) < 0) { fprintf(stderr, "Flush terminated\n"); exit(1); } @@ -1486,10 +1451,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) ipaddr_reset_filter(oneline, 0); filter.showqueue = 1; - - if (filter.family == AF_UNSPEC) - filter.family = preferred_family; - + filter.family = preferred_family; filter.group = -1; if (action == IPADD_FLUSH) { diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c index 473ff97a..db29bf03 100644 --- a/ip/iplink_vxlan.c +++ b/ip/iplink_vxlan.c @@ -30,6 +30,7 @@ static void print_explain(FILE *f) fprintf(f, " [ [no]l2miss ] [ [no]l3miss ]\n"); fprintf(f, " [ ageing SECONDS ] [ maxaddress NUMBER ]\n"); fprintf(f, " [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]\n"); + fprintf(f, " [ [no]remcsumtx ] [ [no]remcsumrx ]\n"); fprintf(f, " [ gbp ]\n"); fprintf(f, "\n"); fprintf(f, "Where: VNI := 0-16777215\n"); @@ -69,6 +70,8 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, __u8 udpcsum = 0; __u8 udp6zerocsumtx = 0; __u8 udp6zerocsumrx = 0; + __u8 remcsumtx = 0; + __u8 remcsumrx = 0; __u8 gbp = 0; int dst_port_set = 0; struct ifla_vxlan_port_range range = { 0, 0 }; @@ -199,6 +202,14 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, udp6zerocsumrx = 1; } else if (!matches(*argv, "noudp6zerocsumrx")) { udp6zerocsumrx = 0; + } else if (!matches(*argv, "remcsumtx")) { + remcsumtx = 1; + } else if (!matches(*argv, "noremcsumtx")) { + remcsumtx = 0; + } else if (!matches(*argv, "remcsumrx")) { + remcsumrx = 1; + } else if (!matches(*argv, "noremcsumrx")) { + remcsumrx = 0; } else if (!matches(*argv, "gbp")) { gbp = 1; } else if (matches(*argv, "help") == 0) { @@ -259,6 +270,8 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, addattr8(n, 1024, IFLA_VXLAN_UDP_CSUM, udpcsum); addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, udp6zerocsumtx); addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx); + addattr8(n, 1024, IFLA_VXLAN_REMCSUM_TX, remcsumtx); + addattr8(n, 1024, IFLA_VXLAN_REMCSUM_RX, remcsumrx); if (noage) addattr32(n, 1024, IFLA_VXLAN_AGEING, 0); @@ -407,6 +420,14 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX])) fputs("udp6zerocsumrx ", f); + if (tb[IFLA_VXLAN_REMCSUM_TX] && + rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_TX])) + fputs("remcsumtx ", f); + + if (tb[IFLA_VXLAN_REMCSUM_RX] && + rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_RX])) + fputs("remcsumrx ", f); + if (tb[IFLA_VXLAN_GBP]) fputs("gbp ", f); } diff --git a/ip/iproute.c b/ip/iproute.c index c0ef7bfe..aed1038e 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -931,7 +931,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) mxlock |= (1< 255) invarg("\"hoplimit\" value is invalid\n", *argv); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_HOPLIMIT, hoplimit); } else if (strcmp(*argv, "advmss") == 0) { diff --git a/ip/iptoken.c b/ip/iptoken.c index a38194c9..428f1332 100644 --- a/ip/iptoken.c +++ b/ip/iptoken.c @@ -95,10 +95,6 @@ static int iptoken_list(int argc, char **argv) { int af = AF_INET6; struct rtnl_dump_args da; - const struct rtnl_dump_filter_arg a[2] = { - { .filter = print_token, .arg1 = &da, }, - { .filter = NULL, .arg1 = NULL, }, - }; memset(&da, 0, sizeof(da)); da.fp = stdout; @@ -118,7 +114,7 @@ static int iptoken_list(int argc, char **argv) return -1; } - if (rtnl_dump_filter_l(&rth, a) < 0) { + if (rtnl_dump_filter(&rth, print_token, &da) < 0) { fprintf(stderr, "Dump terminated\n"); return -1; } diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 09b0e911..922ec2d9 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -259,6 +259,8 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, while (NLMSG_OK(h, msglen)) { int err = 0; + h->nlmsg_flags &= ~a->nc_flags; + if (nladdr.nl_pid != 0 || h->nlmsg_pid != rth->local.nl_pid || h->nlmsg_seq != rth->dump) @@ -317,13 +319,13 @@ skip_it: } } -int rtnl_dump_filter(struct rtnl_handle *rth, +int rtnl_dump_filter_nc(struct rtnl_handle *rth, rtnl_filter_t filter, - void *arg1) + void *arg1, __u16 nc_flags) { const struct rtnl_dump_filter_arg a[2] = { - { .filter = filter, .arg1 = arg1, }, - { .filter = NULL, .arg1 = NULL, }, + { .filter = filter, .arg1 = arg1, .nc_flags = nc_flags, }, + { .filter = NULL, .arg1 = NULL, .nc_flags = 0, }, }; return rtnl_dump_filter_l(rth, a); diff --git a/lib/rt_names.c b/lib/rt_names.c index e87c65da..1071a938 100644 --- a/lib/rt_names.c +++ b/lib/rt_names.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -30,8 +31,8 @@ #define NAME_MAX_LEN 512 struct rtnl_hash_entry { - struct rtnl_hash_entry *next; - const char * name; + struct rtnl_hash_entry *next; + const char *name; unsigned int id; }; @@ -81,7 +82,7 @@ rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size) return; } - if (id<0) + if (id < 0) continue; entry = malloc(sizeof(*entry)); @@ -111,7 +112,7 @@ static void rtnl_tab_initialize(const char *file, char **tab, int size) fclose(fp); return; } - if (id<0 || id>size) + if (id < 0 || id > size) continue; tab[id] = strdup(namebuf); @@ -119,23 +120,23 @@ static void rtnl_tab_initialize(const char *file, char **tab, int size) fclose(fp); } -static char * rtnl_rtprot_tab[256] = { - [RTPROT_UNSPEC] = "none", - [RTPROT_REDIRECT] ="redirect", - [RTPROT_KERNEL] = "kernel", - [RTPROT_BOOT] = "boot", - [RTPROT_STATIC] = "static", +static char *rtnl_rtprot_tab[256] = { + [RTPROT_UNSPEC] = "none", + [RTPROT_REDIRECT] = "redirect", + [RTPROT_KERNEL] = "kernel", + [RTPROT_BOOT] = "boot", + [RTPROT_STATIC] = "static", - [RTPROT_GATED] = "gated", - [RTPROT_RA] = "ra", - [RTPROT_MRT] = "mrt", - [RTPROT_ZEBRA] ="zebra", - [RTPROT_BIRD] = "bird", - [RTPROT_BABEL] = "babel", + [RTPROT_GATED] = "gated", + [RTPROT_RA] = "ra", + [RTPROT_MRT] = "mrt", + [RTPROT_ZEBRA] = "zebra", + [RTPROT_BIRD] = "bird", + [RTPROT_BABEL] = "babel", [RTPROT_DNROUTED] = "dnrouted", - [RTPROT_XORP] = "xorp", - [RTPROT_NTK] = "ntk", - [RTPROT_DHCP] = "dhcp", + [RTPROT_XORP] = "xorp", + [RTPROT_NTK] = "ntk", + [RTPROT_DHCP] = "dhcp", }; @@ -148,9 +149,9 @@ static void rtnl_rtprot_initialize(void) rtnl_rtprot_tab, 256); } -const char * rtnl_rtprot_n2a(int id, char *buf, int len) +const char *rtnl_rtprot_n2a(int id, char *buf, int len) { - if (id<0 || id>=256) { + if (id < 0 || id >= 256) { snprintf(buf, len, "%u", id); return buf; } @@ -166,7 +167,7 @@ const char * rtnl_rtprot_n2a(int id, char *buf, int len) int rtnl_rtprot_a2n(__u32 *id, const char *arg) { - static char *cache = NULL; + static char *cache; static unsigned long res; char *end; int i; @@ -179,7 +180,7 @@ int rtnl_rtprot_a2n(__u32 *id, const char *arg) if (!rtnl_rtprot_init) rtnl_rtprot_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { if (rtnl_rtprot_tab[i] && strcmp(rtnl_rtprot_tab[i], arg) == 0) { cache = rtnl_rtprot_tab[i]; @@ -196,8 +197,13 @@ int rtnl_rtprot_a2n(__u32 *id, const char *arg) return 0; } -static char * rtnl_rtscope_tab[256] = { - "global", + +static char *rtnl_rtscope_tab[256] = { + [RT_SCOPE_UNIVERSE] = "global", + [RT_SCOPE_NOWHERE] = "nowhere", + [RT_SCOPE_HOST] = "host", + [RT_SCOPE_LINK] = "link", + [RT_SCOPE_SITE] = "site", }; static int rtnl_rtscope_init; @@ -205,33 +211,32 @@ static int rtnl_rtscope_init; static void rtnl_rtscope_initialize(void) { rtnl_rtscope_init = 1; - rtnl_rtscope_tab[RT_SCOPE_NOWHERE] = "nowhere"; - rtnl_rtscope_tab[RT_SCOPE_HOST] = "host"; - rtnl_rtscope_tab[RT_SCOPE_LINK] = "link"; - rtnl_rtscope_tab[RT_SCOPE_SITE] = "site"; rtnl_tab_initialize(CONFDIR "/rt_scopes", rtnl_rtscope_tab, 256); } const char *rtnl_rtscope_n2a(int id, char *buf, int len) { - if (id<0 || id>=256) { + if (id < 0 || id >= 256) { snprintf(buf, len, "%d", id); return buf; } + if (!rtnl_rtscope_tab[id]) { if (!rtnl_rtscope_init) rtnl_rtscope_initialize(); } + if (rtnl_rtscope_tab[id]) return rtnl_rtscope_tab[id]; + snprintf(buf, len, "%d", id); return buf; } int rtnl_rtscope_a2n(__u32 *id, const char *arg) { - static const char *cache = NULL; + static const char *cache; static unsigned long res; char *end; int i; @@ -244,7 +249,7 @@ int rtnl_rtscope_a2n(__u32 *id, const char *arg) if (!rtnl_rtscope_init) rtnl_rtscope_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { if (rtnl_rtscope_tab[i] && strcmp(rtnl_rtscope_tab[i], arg) == 0) { cache = rtnl_rtscope_tab[i]; @@ -262,7 +267,7 @@ int rtnl_rtscope_a2n(__u32 *id, const char *arg) } -static char * rtnl_rtrealm_tab[256] = { +static char *rtnl_rtrealm_tab[256] = { "unknown", }; @@ -277,7 +282,7 @@ static void rtnl_rtrealm_initialize(void) const char *rtnl_rtrealm_n2a(int id, char *buf, int len) { - if (id<0 || id>=256) { + if (id < 0 || id >= 256) { snprintf(buf, len, "%d", id); return buf; } @@ -294,7 +299,7 @@ const char *rtnl_rtrealm_n2a(int id, char *buf, int len) int rtnl_rtrealm_a2n(__u32 *id, const char *arg) { - static char *cache = NULL; + static char *cache; static unsigned long res; char *end; int i; @@ -307,7 +312,7 @@ int rtnl_rtrealm_a2n(__u32 *id, const char *arg) if (!rtnl_rtrealm_init) rtnl_rtrealm_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { if (rtnl_rtrealm_tab[i] && strcmp(rtnl_rtrealm_tab[i], arg) == 0) { cache = rtnl_rtrealm_tab[i]; @@ -329,7 +334,7 @@ static struct rtnl_hash_entry dflt_table_entry = { .name = "default" }; static struct rtnl_hash_entry main_table_entry = { .name = "main" }; static struct rtnl_hash_entry local_table_entry = { .name = "local" }; -static struct rtnl_hash_entry * rtnl_rttable_hash[256] = { +static struct rtnl_hash_entry *rtnl_rttable_hash[256] = { [RT_TABLE_DEFAULT] = &dflt_table_entry, [RT_TABLE_MAIN] = &main_table_entry, [RT_TABLE_LOCAL] = &local_table_entry, @@ -339,6 +344,8 @@ static int rtnl_rttable_init; static void rtnl_rttable_initialize(void) { + struct dirent *de; + DIR *d; int i; rtnl_rttable_init = 1; @@ -348,9 +355,33 @@ static void rtnl_rttable_initialize(void) } rtnl_hash_initialize(CONFDIR "/rt_tables", rtnl_rttable_hash, 256); + + d = opendir(CONFDIR "/rt_tables.d"); + if (!d) + return; + + while ((de = readdir(d)) != NULL) { + char path[PATH_MAX]; + size_t len; + + if (*de->d_name == '.') + continue; + + /* only consider filenames ending in '.conf' */ + len = strlen(de->d_name); + if (len <= 5) + continue; + if (strcmp(de->d_name + len - 5, ".conf")) + continue; + + snprintf(path, sizeof(path), + CONFDIR "/rt_tables.d/%s", de->d_name); + rtnl_hash_initialize(path, rtnl_rttable_hash, 256); + } + closedir(d); } -const char * rtnl_rttable_n2a(__u32 id, char *buf, int len) +const char *rtnl_rttable_n2a(__u32 id, char *buf, int len) { struct rtnl_hash_entry *entry; @@ -371,7 +402,7 @@ const char * rtnl_rttable_n2a(__u32 id, char *buf, int len) int rtnl_rttable_a2n(__u32 *id, const char *arg) { - static const char *cache = NULL; + static const char *cache; static unsigned long res; struct rtnl_hash_entry *entry; char *end; @@ -385,7 +416,7 @@ int rtnl_rttable_a2n(__u32 *id, const char *arg) if (!rtnl_rttable_init) rtnl_rttable_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { entry = rtnl_rttable_hash[i]; while (entry && strcmp(entry->name, arg)) entry = entry->next; @@ -405,7 +436,7 @@ int rtnl_rttable_a2n(__u32 *id, const char *arg) } -static char * rtnl_rtdsfield_tab[256] = { +static char *rtnl_rtdsfield_tab[256] = { "0", }; @@ -420,7 +451,7 @@ static void rtnl_rtdsfield_initialize(void) const char *rtnl_dsfield_n2a(int id, char *buf, int len) { - if (id<0 || id>=256) { + if (id < 0 || id >= 256) { snprintf(buf, len, "%d", id); return buf; } @@ -437,7 +468,7 @@ const char *rtnl_dsfield_n2a(int id, char *buf, int len) int rtnl_dsfield_a2n(__u32 *id, const char *arg) { - static char *cache = NULL; + static char *cache; static unsigned long res; char *end; int i; @@ -450,7 +481,7 @@ int rtnl_dsfield_a2n(__u32 *id, const char *arg) if (!rtnl_rtdsfield_init) rtnl_rtdsfield_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { if (rtnl_rtdsfield_tab[i] && strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { cache = rtnl_rtdsfield_tab[i]; @@ -468,9 +499,11 @@ int rtnl_dsfield_a2n(__u32 *id, const char *arg) } -static struct rtnl_hash_entry dflt_group_entry = { .id = 0, .name = "default" }; +static struct rtnl_hash_entry dflt_group_entry = { + .id = 0, .name = "default" +}; -static struct rtnl_hash_entry * rtnl_group_hash[256] = { +static struct rtnl_hash_entry *rtnl_group_hash[256] = { [0] = &dflt_group_entry, }; @@ -485,7 +518,7 @@ static void rtnl_group_initialize(void) int rtnl_group_a2n(int *id, const char *arg) { - static const char *cache = NULL; + static const char *cache; static unsigned long res; struct rtnl_hash_entry *entry; char *end; @@ -499,7 +532,7 @@ int rtnl_group_a2n(int *id, const char *arg) if (!rtnl_group_init) rtnl_group_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { entry = rtnl_group_hash[i]; while (entry && strcmp(entry->name, arg)) entry = entry->next; @@ -526,11 +559,10 @@ const char *rtnl_group_n2a(int id, char *buf, int len) if (!rtnl_group_init) rtnl_group_initialize(); - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { entry = rtnl_group_hash[i]; - if (entry && entry->id == id) { + if (entry && entry->id == id) return entry->name; - } } snprintf(buf, len, "%d", id); @@ -589,7 +621,7 @@ const char *nl_proto_n2a(int id, char *buf, int len) int nl_proto_a2n(__u32 *id, const char *arg) { - static char *cache = NULL; + static char *cache; static unsigned long res; char *end; int i; diff --git a/man/man8/bridge.8 b/man/man8/bridge.8 index 98a92eb8..0ec6f174 100644 --- a/man/man8/bridge.8 +++ b/man/man8/bridge.8 @@ -25,14 +25,14 @@ bridge \- show / manipulate bridge addresses and devices .ti -8 .BR "bridge link set" -.B dev +.B dev .IR DEV .IR " [ " -.B cost +.B cost .IR COST " ] [ " -.B priority -.IR PRIO " ] [ " -.B state +.B priority +.IR PRIO " ] [ " +.B state .IR STATE "] [" .BR guard " { " on " | " off " } ] [ " .BR hairpin " { " on " | " off " } ] [ " @@ -42,21 +42,21 @@ bridge \- show / manipulate bridge addresses and devices .BR learning_sync " { " on " | " off " } ] [ " .BR flood " { " on " | " off " } ] [ " .BR hwmode " { " vepa " | " veb " } ] [ " -.BR self " ] [ " master " ] " +.BR self " ] [ " master " ] " .ti -8 .BR "bridge link" " [ " show " ] [ " -.B dev +.B dev .IR DEV " ]" .ti -8 .BR "bridge fdb" " { " add " | " append " | " del " | " replace " } " .I LLADDR -.B dev +.B dev .IR DEV " { " .BR local " | " temp " } [ " .BR self " ] [ " master " ] [ " router " ] [ " use " ] [ " -.B dst +.B dst .IR IPADDR " ] [ " .B vni .IR VNI " ] [" @@ -67,12 +67,12 @@ bridge \- show / manipulate bridge addresses and devices .ti -8 .BR "bridge fdb" " [ " show " ] [ " -.B dev +.B dev .IR DEV " ]" .ti -8 .BR "bridge mdb" " { " add " | " del " } " -.B dev +.B dev .IR DEV .B port .IR PORT @@ -84,21 +84,21 @@ bridge \- show / manipulate bridge addresses and devices .ti -8 .BR "bridge mdb show " [ " -.B dev +.B dev .IR DEV " ]" .ti -8 .BR "bridge vlan" " { " add " | " del " } " -.B dev +.B dev .IR DEV -.B vid +.B vid .IR VID " [ " -.BR pvid " ] [ " untagged " ] [ " -.BR self " ] [ " master " ] " +.BR pvid " ] [ " untagged " ] [ " +.BR self " ] [ " master " ] " .ti -8 .BR "bridge vlan" " [ " show " ] [ " -.B dev +.B dev .IR DEV " ]" .ti -8 @@ -319,7 +319,7 @@ This command displays the current bridge port configuration and flags. .SH bridge fdb - forwarding database management .B fdb -objects contain known Ethernet addresses on a link. +objects contain known Ethernet addresses on a link. .P The corresponding commands display fdb entries, add new entries, @@ -398,21 +398,21 @@ sends a copy of the data packet to each entry found. .PP The arguments are the same as with -.BR "bridge fdb add" , +.BR "bridge fdb add" . .SS bridge fdb delete - delete a forwarding database entry This command removes an existing fdb entry. .PP The arguments are the same as with -.BR "bridge fdb add" , +.BR "bridge fdb add" . .SS bridge fdb replace - replace a forwarding database entry If no matching entry is found, a new one will be created instead. .PP The arguments are the same as with -.BR "bridge fdb add" , +.BR "bridge fdb add" . .SS bridge fdb show - list forwarding entries. @@ -548,7 +548,7 @@ This command displays the current VLAN filter table. The .B bridge -utility can monitor the state of devices and addresses +utility can monitor the state of devices and addresses continuously. This option has a slightly different format. Namely, the .B monitor @@ -560,7 +560,7 @@ command is the first in the command line and then the object list follows: .I OBJECT-LIST is the list of object types that we want to monitor. It may contain -.BR link ", " fdb ", and " mdb "." +.BR link ", " fdb ", and " mdb "." If no .B file argument is given, diff --git a/misc/arpd.c b/misc/arpd.c index 7919eb8b..6bb9bd16 100644 --- a/misc/arpd.c +++ b/misc/arpd.c @@ -703,7 +703,7 @@ int main(int argc, char **argv) } buf[sizeof(buf)-1] = 0; - while (fgets(buf, sizeof(buf)-1, fp)) { + while (fgets(buf, sizeof(buf), fp)) { __u8 b1[6]; char ipbuf[128]; char macbuf[128]; diff --git a/misc/ifstat.c b/misc/ifstat.c index 20a8db45..ac5c29c8 100644 --- a/misc/ifstat.c +++ b/misc/ifstat.c @@ -819,7 +819,8 @@ int main(int argc, char *argv[]) } if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) { fprintf(stderr, "ifstat: history is aged out, resetting\n"); - ftruncate(fileno(hist_fp), 0); + if (ftruncate(fileno(hist_fp), 0)) + perror("ifstat: ftruncate"); } } @@ -862,7 +863,8 @@ int main(int argc, char *argv[]) } if (!no_update) { - ftruncate(fileno(hist_fp), 0); + if (ftruncate(fileno(hist_fp), 0)) + perror("ifstat: ftruncate"); rewind(hist_fp); json_output = 0; diff --git a/misc/lnstat_util.c b/misc/lnstat_util.c index 6dde7c49..70a77c56 100644 --- a/misc/lnstat_util.c +++ b/misc/lnstat_util.c @@ -38,18 +38,22 @@ /* Read (and summarize for SMP) the different stats vars. */ static int scan_lines(struct lnstat_file *lf, int i) { + char buf[FGETS_BUF_SIZE]; int j, num_lines = 0; for (j = 0; j < lf->num_fields; j++) lf->fields[j].values[i] = 0; - while(!feof(lf->fp)) { - char buf[FGETS_BUF_SIZE]; + rewind(lf->fp); + /* skip first line */ + if (!lf->compat && !fgets(buf, sizeof(buf)-1, lf->fp)) + return -1; + + while(!feof(lf->fp) && fgets(buf, sizeof(buf)-1, lf->fp)) { char *ptr = buf; num_lines++; - fgets(buf, sizeof(buf)-1, lf->fp); gettimeofday(&lf->last_read, NULL); for (j = 0; j < lf->num_fields; j++) { @@ -81,7 +85,6 @@ static int time_after(struct timeval *last, int lnstat_update(struct lnstat_file *lnstat_files) { struct lnstat_file *lf; - char buf[FGETS_BUF_SIZE]; struct timeval tv; gettimeofday(&tv, NULL); @@ -91,11 +94,6 @@ int lnstat_update(struct lnstat_file *lnstat_files) int i; struct lnstat_field *lfi; - rewind(lf->fp); - if (!lf->compat) { - /* skip first line */ - fgets(buf, sizeof(buf)-1, lf->fp); - } scan_lines(lf, 1); for (i = 0, lfi = &lf->fields[i]; @@ -107,8 +105,6 @@ int lnstat_update(struct lnstat_file *lnstat_files) / lf->interval.tv_sec; } - rewind(lf->fp); - fgets(buf, sizeof(buf)-1, lf->fp); scan_lines(lf, 0); } } @@ -142,7 +138,8 @@ static int lnstat_scan_fields(struct lnstat_file *lf) char buf[FGETS_BUF_SIZE]; rewind(lf->fp); - fgets(buf, sizeof(buf)-1, lf->fp); + if (!fgets(buf, sizeof(buf)-1, lf->fp)) + return -1; return __lnstat_scan_fields(lf, buf); } diff --git a/misc/nstat.c b/misc/nstat.c index 267e515f..99705286 100644 --- a/misc/nstat.c +++ b/misc/nstat.c @@ -649,7 +649,8 @@ int main(int argc, char *argv[]) } if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) { fprintf(stderr, "nstat: history is aged out, resetting\n"); - ftruncate(fileno(hist_fp), 0); + if (ftruncate(fileno(hist_fp), 0) < 0) + perror("nstat: ftruncate"); } } @@ -693,7 +694,8 @@ int main(int argc, char *argv[]) dump_incr_db(stdout); } if (!no_update) { - ftruncate(fileno(hist_fp), 0); + if (ftruncate(fileno(hist_fp), 0) < 0) + perror("nstat: ftruncate"); rewind(hist_fp); json_output = 0; diff --git a/misc/ss.c b/misc/ss.c index a9ae85ec..0dab32ce 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -528,7 +528,8 @@ static void user_ent_hash_build(void) snprintf(tmp, sizeof(tmp), "%s/%d/stat", root, pid); if ((fp = fopen(tmp, "r")) != NULL) { - fscanf(fp, "%*d (%[^)])", p); + if (fscanf(fp, "%*d (%[^)])", p) < 1) + ; /* ignore */ fclose(fp); } } @@ -660,7 +661,10 @@ static int get_slabstat(struct slabstat *s) cnt = sizeof(*s)/sizeof(int); - fgets(buf, sizeof(buf), fp); + if (!fgets(buf, sizeof(buf), fp)) { + fclose(fp); + return -1; + } while(fgets(buf, sizeof(buf), fp) != NULL) { int i; for (i=0; i/dev/null", "r"); - if (fp) { - fgets(buf, sizeof(buf), fp); - while (fgets(buf, sizeof(buf), fp) != NULL) { - unsigned int progn, port; - char proto[128], prog[128]; - if (sscanf(buf, "%u %*d %s %u %s", &progn, proto, - &port, prog+4) == 4) { - struct scache *c = malloc(sizeof(*c)); - if (c) { - c->port = port; - memcpy(prog, "rpc.", 4); - c->name = strdup(prog); - if (strcmp(proto, TCP_PROTO) == 0) - c->proto = TCP_PROTO; - else if (strcmp(proto, UDP_PROTO) == 0) - c->proto = UDP_PROTO; - else - c->proto = NULL; - c->next = rlist; - rlist = c; - } - } - } - pclose(fp); - } -} -static int ip_local_port_min, ip_local_port_max; + if (!fp) + return; + + if (!fgets(buf, sizeof(buf), fp)) { + pclose(fp); + return; + } + while (fgets(buf, sizeof(buf), fp) != NULL) { + unsigned int progn, port; + char proto[128], prog[128] = "rpc."; + struct scache *c; + + if (sscanf(buf, "%u %*d %s %u %s", + &progn, proto, &port, prog+4) != 4) + continue; + + if (!(c = malloc(sizeof(*c)))) + continue; + + c->port = port; + c->name = strdup(prog); + if (strcmp(proto, TCP_PROTO) == 0) + c->proto = TCP_PROTO; + else if (strcmp(proto, UDP_PROTO) == 0) + c->proto = UDP_PROTO; + else + c->proto = NULL; + c->next = rlist; + rlist = c; + } + pclose(fp); +} /* Even do not try default linux ephemeral port ranges: * default /etc/services contains so much of useless crap @@ -907,19 +916,18 @@ static int ip_local_port_min, ip_local_port_max; */ static int is_ephemeral(int port) { - if (!ip_local_port_min) { - FILE *f = ephemeral_ports_open(); - if (f) { - fscanf(f, "%d %d", - &ip_local_port_min, &ip_local_port_max); - fclose(f); - } else { - ip_local_port_min = 1024; - ip_local_port_max = 4999; - } - } + static int min = 0, max = 0; - return (port >= ip_local_port_min && port<= ip_local_port_max); + if (!min) { + FILE *f = ephemeral_ports_open(); + if (!f || fscanf(f, "%d %d", &min, &max) < 2) { + min = 1024; + max = 4999; + } + if (f) + fclose(f); + } + return port >= min && port <= max; } @@ -1074,8 +1082,6 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s) switch (f->type) { case SSF_S_AUTO: { - static int low, high=65535; - if (s->local.family == AF_UNIX) { char *p; memcpy(&p, s->local.data, sizeof(p)); @@ -1087,14 +1093,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s) if (s->local.family == AF_NETLINK) return s->lport < 0; - if (!low) { - FILE *fp = ephemeral_ports_open(); - if (fp) { - fscanf(fp, "%d%d", &low, &high); - fclose(fp); - } - } - return s->lport >= low && s->lport <= high; + return is_ephemeral(s->lport); } case SSF_DCOND: { @@ -2730,13 +2729,16 @@ static int unix_show(struct filter *f) if ((fp = net_unix_open()) == NULL) return -1; - fgets(buf, sizeof(buf)-1, fp); + if (!fgets(buf, sizeof(buf), fp)) { + fclose(fp); + return -1; + } if (memcmp(buf, "Peer", 4) == 0) newformat = 1; cnt = 0; - while (fgets(buf, sizeof(buf)-1, fp)) { + while (fgets(buf, sizeof(buf), fp)) { struct sockstat *u, **insp; int flags; @@ -3215,9 +3217,12 @@ static int netlink_show(struct filter *f) if ((fp = net_netlink_open()) == NULL) return -1; - fgets(buf, sizeof(buf)-1, fp); + if (!fgets(buf, sizeof(buf), fp)) { + fclose(fp); + return -1; + } - while (fgets(buf, sizeof(buf)-1, fp)) { + while (fgets(buf, sizeof(buf), fp)) { sscanf(buf, "%llx %d %d %x %d %d %llx %d", &sk, &prot, &pid, &groups, &rq, &wq, &cb, &rc);