aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@kernel.org>2024-02-18 17:41:39 +0000
committerDavid Ahern <dsahern@kernel.org>2024-02-18 17:41:39 +0000
commitf900302f3295fdde36f508ebfb9a2a68f115fe09 (patch)
treef362e07c2370e3130a96497f995696146d670d58
parente8dcb1214a21241f32405c88680f14cc57266067 (diff)
parentd9b886d745ada3b8481e041ceca579c6f3acbea3 (diff)
downloadiproute2-f900302f3295fdde36f508ebfb9a2a68f115fe09.tar.gz
Merge remote-tracking branch 'main/main' into next
Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r--devlink/devlink.c2
-rw-r--r--examples/bpf/README2
-rw-r--r--genl/ctrl.c7
-rw-r--r--include/bpf_api.h2
-rw-r--r--include/xt-internal.h2
-rw-r--r--ip/ip.c8
-rw-r--r--ip/ipnetconf.c3
-rw-r--r--ip/ipnetns.c3
-rw-r--r--lib/bpf_legacy.c5
-rw-r--r--lib/color.c3
-rw-r--r--lib/json_print.c2
-rw-r--r--lib/utils.c2
-rw-r--r--man/man8/devlink-rate.82
-rw-r--r--man/man8/ip-l2tp.82
-rw-r--r--man/man8/tc-htb.82
-rw-r--r--man/man8/tc-sfb.82
-rw-r--r--man/man8/tipc-nametable.84
-rw-r--r--misc/ifstat.c26
-rw-r--r--rdma/rdma.h2
-rw-r--r--tc/em_canid.c2
-rw-r--r--tc/f_fw.c22
-rw-r--r--tc/f_u32.c8
-rw-r--r--tc/m_action.c2
-rw-r--r--tc/m_bpf.c2
-rw-r--r--tc/m_gact.c2
-rw-r--r--tc/q_htb.c2
-rw-r--r--tc/q_netem.c2
-rw-r--r--tc/tc_util.h1
-rw-r--r--tipc/README4
29 files changed, 77 insertions, 51 deletions
diff --git a/devlink/devlink.c b/devlink/devlink.c
index f999e5940..dbeb6e397 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2329,7 +2329,7 @@ static int dl_argv_dry_parse(struct dl *dl, uint64_t o_required,
return err;
}
-/* List of extented handles with two slashes. */
+/* List of extended handles with two slashes. */
static const uint64_t dl_opt_extended_handle[] = {
DL_OPT_HANDLEP,
DL_OPT_HANDLE_REGION,
diff --git a/examples/bpf/README b/examples/bpf/README
index b7261191f..4c27bb4e8 100644
--- a/examples/bpf/README
+++ b/examples/bpf/README
@@ -15,4 +15,4 @@ with syntax and features:
Note: Users should use new BTF way to defined the maps, the examples
in legacy folder which is using struct bpf_elf_map defined maps is not
-recommanded.
+recommended.
diff --git a/genl/ctrl.c b/genl/ctrl.c
index aff922a43..72a9b0130 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -267,7 +267,7 @@ static int ctrl_list(int cmd, int argc, char **argv)
if (argc != 2) {
fprintf(stderr, "Wrong number of params\n");
- return -1;
+ goto ctrl_done;
}
if (matches(*argv, "name") == 0) {
@@ -334,8 +334,9 @@ static int ctrl_listen(int argc, char **argv)
}
if (rtnl_listen(&rth, print_ctrl, (void *) stdout) < 0)
- return -1;
-
+ exit(2);
+
+ rtnl_close(&rth);
return 0;
}
diff --git a/include/bpf_api.h b/include/bpf_api.h
index 5887d3a85..287f96b62 100644
--- a/include/bpf_api.h
+++ b/include/bpf_api.h
@@ -253,7 +253,7 @@ static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
# define memmove(d, s, n) __builtin_memmove((d), (s), (n))
#endif
-/* FIXME: __builtin_memcmp() is not yet fully useable unless llvm bug
+/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
* https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
* this one would generate a reloc entry (non-map), otherwise.
*/
diff --git a/include/xt-internal.h b/include/xt-internal.h
index 89c73e4fe..072161409 100644
--- a/include/xt-internal.h
+++ b/include/xt-internal.h
@@ -6,7 +6,7 @@
# define XT_LIB_DIR "/lib/xtables"
#endif
-/* protocol family dependent informations */
+/* protocol family dependent information */
struct afinfo {
/* protocol family */
int family;
diff --git a/ip/ip.c b/ip/ip.c
index 860ff957c..e51fa206d 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -61,16 +61,16 @@ static void usage(void)
fprintf(stderr,
"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
" ip [ -force ] -batch filename\n"
- "where OBJECT := { address | addrlabel | amt | fou | help | ila | ioam | l2tp |\n"
- " link | macsec | maddress | monitor | mptcp | mroute | mrule |\n"
+ "where OBJECT := { address | addrlabel | fou | help | ila | ioam | l2tp | link |\n"
+ " macsec | maddress | monitor | mptcp | mroute | mrule |\n"
" neighbor | neighbour | netconf | netns | nexthop | ntable |\n"
- " ntbl | route | rule | sr | tap | tcpmetrics |\n"
+ " ntbl | route | rule | sr | stats | tap | tcpmetrics |\n"
" token | tunnel | tuntap | vrf | xfrm }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
" -f[amily] { inet | inet6 | mpls | bridge | link } |\n"
" -4 | -6 | -M | -B | -0 |\n"
- " -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n"
+ " -l[oops] { maximum-addr-flush-attempts } | -echo | -br[ief] |\n"
" -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
" -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |\n"
" -c[olor]}\n");
diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c
index 9ae6c45e7..a0c7e051b 100644
--- a/ip/ipnetconf.c
+++ b/ip/ipnetconf.c
@@ -193,7 +193,8 @@ static int do_show(int argc, char **argv)
perror("Can not send request");
exit(1);
}
- rtnl_listen(&rth, print_netconf, stdout);
+ if (rtnl_listen(&rth, print_netconf, stdout) < 0)
+ exit(2);
} else {
rth.flags = RTNL_HANDLE_F_SUPPRESS_NLERR;
dump:
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 0ae46a874..594b2ef15 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -96,7 +96,8 @@ static int ipnetns_have_nsid(void)
close(fd);
return 0;
}
- rtnl_listen(&rth, ipnetns_accept_msg, NULL);
+ if (rtnl_listen(&rth, ipnetns_accept_msg, NULL) < 0)
+ exit(2);
close(fd);
}
diff --git a/lib/bpf_legacy.c b/lib/bpf_legacy.c
index 844974e97..c8da4a3e6 100644
--- a/lib/bpf_legacy.c
+++ b/lib/bpf_legacy.c
@@ -18,6 +18,7 @@
#include <stdarg.h>
#include <limits.h>
#include <assert.h>
+#include <libgen.h>
#ifdef HAVE_ELF
#include <libelf.h>
@@ -971,8 +972,8 @@ int bpf_load_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops,
ops->cbpf_cb(nl, cfg->opcodes, cfg->n_opcodes);
if (cfg->mode == EBPF_OBJECT || cfg->mode == EBPF_PINNED) {
snprintf(annotation, sizeof(annotation), "%s:[%s]",
- basename(cfg->object), cfg->mode == EBPF_PINNED ?
- "*fsobj" : cfg->section);
+ basename(strdupa(cfg->object)),
+ cfg->mode == EBPF_PINNED ? "*fsobj" : cfg->section);
ops->ebpf_cb(nl, cfg->prog_fd, annotation);
}
diff --git a/lib/color.c b/lib/color.c
index 599768472..cd0f9f750 100644
--- a/lib/color.c
+++ b/lib/color.c
@@ -140,6 +140,9 @@ int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
int ret = 0;
va_list args;
+ if (fmt == NULL)
+ return 0;
+
va_start(args, fmt);
if (!color_is_enabled || attr == COLOR_NONE) {
diff --git a/lib/json_print.c b/lib/json_print.c
index 7b3b6c3fa..810d496e9 100644
--- a/lib/json_print.c
+++ b/lib/json_print.c
@@ -217,7 +217,7 @@ int print_color_bool(enum output_type type,
/* In JSON mode, acts like print_color_bool.
* Otherwise, will print key with prefix of "no" if false.
- * The show flag is used to suppres printing in non-JSON mode
+ * The show flag is used to suppress printing in non-JSON mode
*/
int print_color_bool_opt(enum output_type type,
enum color_attr color,
diff --git a/lib/utils.c b/lib/utils.c
index 599e859ea..6c1c1a8d3 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1582,7 +1582,7 @@ size_t strlcat(char *dst, const char *src, size_t size)
void drop_cap(void)
{
#ifdef HAVE_LIBCAP
- /* don't harmstring root/sudo */
+ /* don't hamstring root/sudo */
if (getuid() != 0 && geteuid() != 0) {
cap_t capabilities;
cap_value_t net_admin = CAP_NET_ADMIN;
diff --git a/man/man8/devlink-rate.8 b/man/man8/devlink-rate.8
index bcec3c316..f09ac4acb 100644
--- a/man/man8/devlink-rate.8
+++ b/man/man8/devlink-rate.8
@@ -149,7 +149,7 @@ These parameter accept integer meaning weight or priority of a node.
- set rate object parent to existing node with name \fINODE_NAME\fR or unset
parent. Rate limits of the parent node applied to all it's children. Actual
behaviour is details of driver's implementation. Setting parent to empty ("")
-name due to the kernel logic threated as parent unset.
+name due to the kernel logic treated as parent unset.
.SS devlink port function rate add - create node rate object with specified parameters.
Creates rate object of type node and sets parameters. Parameters same as for the
diff --git a/man/man8/ip-l2tp.8 b/man/man8/ip-l2tp.8
index 9aba6becf..7109c0a0b 100644
--- a/man/man8/ip-l2tp.8
+++ b/man/man8/ip-l2tp.8
@@ -392,7 +392,7 @@ If L2TP is being used over IPv6, use the IPv6 defrag module.
.SH INTEROPERABILITY
.PP
Unmanaged (static) L2TPv3 tunnels are supported by some network
-equipment equipment vendors such as Cisco.
+equipment vendors such as Cisco.
.PP
In Linux, L2TP Hello messages are not supported in unmanaged
tunnels. Hello messages are used by L2TP clients and servers to detect
diff --git a/man/man8/tc-htb.8 b/man/man8/tc-htb.8
index 7aa626154..59b159fb5 100644
--- a/man/man8/tc-htb.8
+++ b/man/man8/tc-htb.8
@@ -36,7 +36,7 @@ bytes
.SH DESCRIPTION
HTB allows control of the outbound bandwidth on a given link.
-It allows simulating simulating several slower links and to send different
+It allows simulating several slower links and to send different
kinds of traffic on different simulated links. In both cases, you have
to specify how to divide the physical link into simulated links and
how to decide which simulated link to use for a given packet to be sent.
diff --git a/man/man8/tc-sfb.8 b/man/man8/tc-sfb.8
index e4584deb7..1f2b8c5e3 100644
--- a/man/man8/tc-sfb.8
+++ b/man/man8/tc-sfb.8
@@ -67,7 +67,7 @@ the number of non-responsive flows, M. It is (1 - (1 - (1 / 16.0)) ** M) **8,
so for example with 10 non-responsive flows approximately 0.2% of responsive flows
will be misidentified.
-To mitigate this, SFB performs performs periodic re-hashing to avoid
+To mitigate this, SFB performs periodic re-hashing to avoid
misclassification for prolonged periods of time.
The default hashing method will use source and destination ip addresses and port numbers
diff --git a/man/man8/tipc-nametable.8 b/man/man8/tipc-nametable.8
index b187d25e1..f7c51f195 100644
--- a/man/man8/tipc-nametable.8
+++ b/man/man8/tipc-nametable.8
@@ -49,13 +49,13 @@ provided by a port.
.B Lower
.br
The lower bound of the 32-bit instance field of the port name.
-The instance field is often used as as a sub-class indicator.
+The instance field is often used as a sub-class indicator.
.TP
.B Upper
.br
The upper bound of the 32-bit instance field of the port name.
-The instance field is often used as as a sub-class indicator.
+The instance field is often used as a sub-class indicator.
A difference in
.BR "lower " "and " upper
means the socket is bound to the port name range [lower,upper]
diff --git a/misc/ifstat.c b/misc/ifstat.c
index f6f9ba502..767cedd4a 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -58,7 +58,7 @@ struct ifstat_ent {
struct ifstat_ent *next;
char *name;
int ifindex;
- __u64 val[MAXS];
+ unsigned long long val[MAXS];
double rate[MAXS];
__u32 ival[MAXS];
};
@@ -117,16 +117,20 @@ static int get_nlmsg_extended(struct nlmsghdr *m, void *arg)
return 0;
len -= NLMSG_LENGTH(sizeof(*ifsm));
- if (len < 0)
+ if (len < 0) {
+ errno = EINVAL;
return -1;
+ }
parse_rtattr(tb, IFLA_STATS_MAX, IFLA_STATS_RTA(ifsm), len);
if (tb[filter_type] == NULL)
return 0;
n = malloc(sizeof(*n));
- if (!n)
- abort();
+ if (!n) {
+ errno = ENOMEM;
+ return -1;
+ }
n->ifindex = ifsm->ifindex;
n->name = strdup(ll_index_to_name(ifsm->ifindex));
@@ -161,8 +165,10 @@ static int get_nlmsg(struct nlmsghdr *m, void *arg)
return 0;
len -= NLMSG_LENGTH(sizeof(*ifi));
- if (len < 0)
+ if (len < 0) {
+ errno = EINVAL;
return -1;
+ }
if (!(ifi->ifi_flags&IFF_UP))
return 0;
@@ -172,8 +178,10 @@ static int get_nlmsg(struct nlmsghdr *m, void *arg)
return 0;
n = malloc(sizeof(*n));
- if (!n)
- abort();
+ if (!n) {
+ errno = ENOMEM;
+ return -1;
+ }
n->ifindex = ifi->ifi_index;
n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS]), sizeof(n->ival));
@@ -204,7 +212,7 @@ static void load_info(void)
}
if (rtnl_dump_filter(&rth, get_nlmsg_extended, NULL) < 0) {
- fprintf(stderr, "Dump terminated\n");
+ perror("Dump terminated\n");
exit(1);
}
} else {
@@ -214,7 +222,7 @@ static void load_info(void)
}
if (rtnl_dump_filter(&rth, get_nlmsg, NULL) < 0) {
- fprintf(stderr, "Dump terminated\n");
+ perror("Dump terminated\n");
exit(1);
}
}
diff --git a/rdma/rdma.h b/rdma/rdma.h
index 1f8f83269..df1852db5 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -40,7 +40,7 @@ struct filter_entry {
char *key;
char *value;
/*
- * This field means that we can try to issue .doit calback
+ * This field means that we can try to issue .doit callback
* on value above. This value can be converted to integer
* with simple atoi(). Otherwise "is_doit" will be false.
*/
diff --git a/tc/em_canid.c b/tc/em_canid.c
index 6d06b66a5..228547529 100644
--- a/tc/em_canid.c
+++ b/tc/em_canid.c
@@ -26,7 +26,7 @@
#include <inttypes.h>
#include "m_ematch.h"
-#define EM_CANID_RULES_MAX 400 /* Main reason for this number is Nelink
+#define EM_CANID_RULES_MAX 400 /* Main reason for this number is Netlink
message size limit equal to Single memory page size. When dump()
is invoked, there are even some ematch related headers sent from
kernel to userspace together with em_canid configuration --
diff --git a/tc/f_fw.c b/tc/f_fw.c
index 38bec492b..fe99cd42e 100644
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -124,18 +124,25 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
if (handle || tb[TCA_FW_MASK]) {
__u32 mark = 0, mask = 0;
+ open_json_object("handle");
if (handle)
mark = handle;
if (tb[TCA_FW_MASK] &&
- (mask = rta_getattr_u32(tb[TCA_FW_MASK])) != 0xFFFFFFFF)
- fprintf(f, "handle 0x%x/0x%x ", mark, mask);
- else
- fprintf(f, "handle 0x%x ", handle);
+ (mask = rta_getattr_u32(tb[TCA_FW_MASK])) != 0xFFFFFFFF) {
+ print_hex(PRINT_ANY, "mark", "handle 0x%x", mark);
+ print_hex(PRINT_ANY, "mask", "/0x%x ", mask);
+ } else {
+ print_hex(PRINT_ANY, "mark", "handle 0x%x ", mark);
+ print_hex(PRINT_JSON, "mask", NULL, 0xFFFFFFFF);
+ }
+ close_json_object();
}
if (tb[TCA_FW_CLASSID]) {
SPRINT_BUF(b1);
- fprintf(f, "classid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_FW_CLASSID]), b1));
+ print_string(PRINT_ANY, "classid", "classid %s ",
+ sprint_tc_classid(
+ rta_getattr_u32(tb[TCA_FW_CLASSID]), b1));
}
if (tb[TCA_FW_POLICE])
@@ -143,11 +150,12 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
if (tb[TCA_FW_INDEV]) {
struct rtattr *idev = tb[TCA_FW_INDEV];
- fprintf(f, "input dev %s ", rta_getattr_str(idev));
+ print_string(PRINT_ANY, "indev", "input dev %s ",
+ rta_getattr_str(idev));
}
if (tb[TCA_FW_ACT]) {
- fprintf(f, "\n");
+ print_string(PRINT_FP, NULL, "\n", "");
tc_print_action(f, tb[TCA_FW_ACT], 0);
}
return 0;
diff --git a/tc/f_u32.c b/tc/f_u32.c
index 936dbd65d..8a2413103 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -7,6 +7,7 @@
*
*/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -87,6 +88,7 @@ static char *sprint_u32_handle(__u32 handle, char *buf)
if (htid) {
int l = snprintf(b, bsize, "%x:", htid>>20);
+ assert(l > 0 && l < bsize);
bsize -= l;
b += l;
}
@@ -94,12 +96,14 @@ static char *sprint_u32_handle(__u32 handle, char *buf)
if (hash) {
int l = snprintf(b, bsize, "%x", hash);
+ assert(l > 0 && l < bsize);
bsize -= l;
b += l;
}
if (nodeid) {
int l = snprintf(b, bsize, ":%x", nodeid);
+ assert(l > 0 && l < bsize);
bsize -= l;
b += l;
}
@@ -1300,7 +1304,7 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
if (tb[TCA_U32_PCNT]) {
if (RTA_PAYLOAD(tb[TCA_U32_PCNT]) < sizeof(*pf)) {
- fprintf(f, "Broken perf counters\n");
+ fprintf(stderr, "Broken perf counters\n");
return -1;
}
pf = RTA_DATA(tb[TCA_U32_PCNT]);
@@ -1315,7 +1319,7 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
struct tc_u32_mark *mark = RTA_DATA(tb[TCA_U32_MARK]);
if (RTA_PAYLOAD(tb[TCA_U32_MARK]) < sizeof(*mark)) {
- fprintf(f, "\n Invalid mark (kernel&iproute2 mismatch)\n");
+ fprintf(stderr, "Invalid mark (kernel&iproute2 mismatch)\n");
} else {
print_nl();
print_0xhex(PRINT_ANY, "fwmark_value", " mark 0x%04x ", mark->val);
diff --git a/tc/m_action.c b/tc/m_action.c
index fd9621e1b..6a361f117 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -62,7 +62,7 @@ static void act_usage(void)
static int print_noaopt(struct action_util *au, FILE *f, struct rtattr *opt)
{
if (opt && RTA_PAYLOAD(opt))
- fprintf(f, "[Unknown action, optlen=%u] ",
+ fprintf(stderr, "[Unknown action, optlen=%u] ",
(unsigned int) RTA_PAYLOAD(opt));
return 0;
}
diff --git a/tc/m_bpf.c b/tc/m_bpf.c
index 4eadcb6da..da50c05e1 100644
--- a/tc/m_bpf.c
+++ b/tc/m_bpf.c
@@ -204,7 +204,7 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg)
}
}
- fprintf(f, "\n ");
+ print_string(PRINT_FP, NULL, "%s", "\n ");
return 0;
}
diff --git a/tc/m_gact.c b/tc/m_gact.c
index e294a701b..225ffce41 100644
--- a/tc/m_gact.c
+++ b/tc/m_gact.c
@@ -18,7 +18,7 @@
#include "tc_util.h"
#include <linux/tc_act/tc_gact.h>
-/* define to turn on probablity stuff */
+/* define to turn on probability stuff */
#ifdef CONFIG_GACT_PROB
static const char *prob_n2a(int p)
diff --git a/tc/q_htb.c b/tc/q_htb.c
index 63b9521b8..9afb293d9 100644
--- a/tc/q_htb.c
+++ b/tc/q_htb.c
@@ -224,7 +224,7 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
opt.ceil.rate = (ceil64 >= (1ULL << 32)) ? ~0U : ceil64;
/* compute minimal allowed burst from rate; mtu is added here to make
- sute that buffer is larger than mtu and to have some safeguard space */
+ sure that buffer is larger than mtu and to have some safeguard space */
if (!buffer)
buffer = rate64 / get_hz() + mtu;
if (!cbuffer)
diff --git a/tc/q_netem.c b/tc/q_netem.c
index 5d5aad808..4ce9ab6e5 100644
--- a/tc/q_netem.c
+++ b/tc/q_netem.c
@@ -117,7 +117,7 @@ static void print_corr(bool present, __u32 value)
}
/*
- * Simplistic file parser for distrbution data.
+ * Simplistic file parser for distribution data.
* Format is:
* # comment line(s)
* data0 data1 ...
diff --git a/tc/tc_util.h b/tc/tc_util.h
index aaf10e433..623d9888a 100644
--- a/tc/tc_util.h
+++ b/tc/tc_util.h
@@ -113,7 +113,6 @@ void print_action_control(FILE *f, const char *prefix,
int action, const char *suffix);
int police_print_xstats(struct action_util *a, FILE *f, struct rtattr *tb);
int tc_print_action(FILE *f, const struct rtattr *tb, unsigned short tot_acts);
-int tc_print_ipt(FILE *f, const struct rtattr *tb);
int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
void print_tm(FILE *f, const struct tcf_t *tm);
int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
diff --git a/tipc/README b/tipc/README
index 578a0b7b5..529d7814f 100644
--- a/tipc/README
+++ b/tipc/README
@@ -13,10 +13,10 @@ possible to create a vlan named "help" with the ip tool, but it's impossible
to remove it, the command just shows help. This is an effect of treating
bare words specially.
-Help texts are not dynamically generated. That is, we do not pass datastructures
+Help texts are not dynamically generated. That is, we do not pass data structures
like command list or option lists and print them dynamically. This is
intentional. There is always that exception and when it comes to help texts
-these exceptions are normally neglected at the expence of usability.
+these exceptions are normally neglected at the expense of usability.
KEY-VALUE
~~~~~~~~~