aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-02 19:40:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-02 19:40:27 -0400
commit8d65b08debc7e62b2c6032d7fe7389d895b92cbc (patch)
tree0c3141b60c3a03cc32742b5750c5e763b9dae489 /lib
parent5a0387a8a8efb90ae7fea1e2e5c62de3efa74691 (diff)
parent5d15af6778b8e4ed1fd41b040283af278e7a9a72 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Millar: "Here are some highlights from the 2065 networking commits that happened this development cycle: 1) XDP support for IXGBE (John Fastabend) and thunderx (Sunil Kowuri) 2) Add a generic XDP driver, so that anyone can test XDP even if they lack a networking device whose driver has explicit XDP support (me). 3) Sparc64 now has an eBPF JIT too (me) 4) Add a BPF program testing framework via BPF_PROG_TEST_RUN (Alexei Starovoitov) 5) Make netfitler network namespace teardown less expensive (Florian Westphal) 6) Add symmetric hashing support to nft_hash (Laura Garcia Liebana) 7) Implement NAPI and GRO in netvsc driver (Stephen Hemminger) 8) Support TC flower offload statistics in mlxsw (Arkadi Sharshevsky) 9) Multiqueue support in stmmac driver (Joao Pinto) 10) Remove TCP timewait recycling, it never really could possibly work well in the real world and timestamp randomization really zaps any hint of usability this feature had (Soheil Hassas Yeganeh) 11) Support level3 vs level4 ECMP route hashing in ipv4 (Nikolay Aleksandrov) 12) Add socket busy poll support to epoll (Sridhar Samudrala) 13) Netlink extended ACK support (Johannes Berg, Pablo Neira Ayuso, and several others) 14) IPSEC hw offload infrastructure (Steffen Klassert)" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (2065 commits) tipc: refactor function tipc_sk_recv_stream() tipc: refactor function tipc_sk_recvmsg() net: thunderx: Optimize page recycling for XDP net: thunderx: Support for XDP header adjustment net: thunderx: Add support for XDP_TX net: thunderx: Add support for XDP_DROP net: thunderx: Add basic XDP support net: thunderx: Cleanup receive buffer allocation net: thunderx: Optimize CQE_TX handling net: thunderx: Optimize RBDR descriptor handling net: thunderx: Support for page recycling ipx: call ipxitf_put() in ioctl error path net: sched: add helpers to handle extended actions qed*: Fix issues in the ptp filter config implementation. qede: Fix concurrency issue in PTP Tx path processing. stmmac: Add support for SIMATIC IOT2000 platform net: hns: fix ethtool_get_strings overflow in hns driver tcp: fix wraparound issue in tcp_lp bpf, arm64: fix jit branch offset related to ldimm64 bpf, arm64: implement jiting of BPF_XADD ...
Diffstat (limited to 'lib')
-rw-r--r--lib/nlattr.c28
-rw-r--r--lib/rhashtable.c33
-rw-r--r--lib/test_bpf.c150
3 files changed, 177 insertions, 34 deletions
diff --git a/lib/nlattr.c b/lib/nlattr.c
index b42b8577fc23..a7e0b16078df 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -112,6 +112,7 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
112 * @len: length of attribute stream 112 * @len: length of attribute stream
113 * @maxtype: maximum attribute type to be expected 113 * @maxtype: maximum attribute type to be expected
114 * @policy: validation policy 114 * @policy: validation policy
115 * @extack: extended ACK report struct
115 * 116 *
116 * Validates all attributes in the specified attribute stream against the 117 * Validates all attributes in the specified attribute stream against the
117 * specified policy. Attributes with a type exceeding maxtype will be 118 * specified policy. Attributes with a type exceeding maxtype will be
@@ -120,20 +121,23 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
120 * Returns 0 on success or a negative error code. 121 * Returns 0 on success or a negative error code.
121 */ 122 */
122int nla_validate(const struct nlattr *head, int len, int maxtype, 123int nla_validate(const struct nlattr *head, int len, int maxtype,
123 const struct nla_policy *policy) 124 const struct nla_policy *policy,
125 struct netlink_ext_ack *extack)
124{ 126{
125 const struct nlattr *nla; 127 const struct nlattr *nla;
126 int rem, err; 128 int rem;
127 129
128 nla_for_each_attr(nla, head, len, rem) { 130 nla_for_each_attr(nla, head, len, rem) {
129 err = validate_nla(nla, maxtype, policy); 131 int err = validate_nla(nla, maxtype, policy);
130 if (err < 0) 132
131 goto errout; 133 if (err < 0) {
134 if (extack)
135 extack->bad_attr = nla;
136 return err;
137 }
132 } 138 }
133 139
134 err = 0; 140 return 0;
135errout:
136 return err;
137} 141}
138EXPORT_SYMBOL(nla_validate); 142EXPORT_SYMBOL(nla_validate);
139 143
@@ -180,7 +184,8 @@ EXPORT_SYMBOL(nla_policy_len);
180 * Returns 0 on success or a negative error code. 184 * Returns 0 on success or a negative error code.
181 */ 185 */
182int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, 186int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
183 int len, const struct nla_policy *policy) 187 int len, const struct nla_policy *policy,
188 struct netlink_ext_ack *extack)
184{ 189{
185 const struct nlattr *nla; 190 const struct nlattr *nla;
186 int rem, err; 191 int rem, err;
@@ -193,8 +198,11 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
193 if (type > 0 && type <= maxtype) { 198 if (type > 0 && type <= maxtype) {
194 if (policy) { 199 if (policy) {
195 err = validate_nla(nla, maxtype, policy); 200 err = validate_nla(nla, maxtype, policy);
196 if (err < 0) 201 if (err < 0) {
202 if (extack)
203 extack->bad_attr = nla;
197 goto errout; 204 goto errout;
205 }
198 } 206 }
199 207
200 tb[type] = (struct nlattr *)nla; 208 tb[type] = (struct nlattr *)nla;
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index f8635fd57442..a930e436db5d 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -535,7 +535,7 @@ static void *rhashtable_lookup_one(struct rhashtable *ht,
535 struct rhash_head *head; 535 struct rhash_head *head;
536 int elasticity; 536 int elasticity;
537 537
538 elasticity = ht->elasticity; 538 elasticity = RHT_ELASTICITY;
539 pprev = rht_bucket_var(tbl, hash); 539 pprev = rht_bucket_var(tbl, hash);
540 rht_for_each_continue(head, *pprev, tbl, hash) { 540 rht_for_each_continue(head, *pprev, tbl, hash) {
541 struct rhlist_head *list; 541 struct rhlist_head *list;
@@ -958,35 +958,20 @@ int rhashtable_init(struct rhashtable *ht,
958 if (params->min_size) 958 if (params->min_size)
959 ht->p.min_size = roundup_pow_of_two(params->min_size); 959 ht->p.min_size = roundup_pow_of_two(params->min_size);
960 960
961 if (params->max_size) 961 /* Cap total entries at 2^31 to avoid nelems overflow. */
962 ht->p.max_size = rounddown_pow_of_two(params->max_size); 962 ht->max_elems = 1u << 31;
963 963
964 if (params->insecure_max_entries) 964 if (params->max_size) {
965 ht->p.insecure_max_entries = 965 ht->p.max_size = rounddown_pow_of_two(params->max_size);
966 rounddown_pow_of_two(params->insecure_max_entries); 966 if (ht->p.max_size < ht->max_elems / 2)
967 else 967 ht->max_elems = ht->p.max_size * 2;
968 ht->p.insecure_max_entries = ht->p.max_size * 2; 968 }
969 969
970 ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE); 970 ht->p.min_size = max_t(u16, ht->p.min_size, HASH_MIN_SIZE);
971 971
972 if (params->nelem_hint) 972 if (params->nelem_hint)
973 size = rounded_hashtable_size(&ht->p); 973 size = rounded_hashtable_size(&ht->p);
974 974
975 /* The maximum (not average) chain length grows with the
976 * size of the hash table, at a rate of (log N)/(log log N).
977 * The value of 16 is selected so that even if the hash
978 * table grew to 2^32 you would not expect the maximum
979 * chain length to exceed it unless we are under attack
980 * (or extremely unlucky).
981 *
982 * As this limit is only to detect attacks, we don't need
983 * to set it to a lower value as you'd need the chain
984 * length to vastly exceed 16 to have any real effect
985 * on the system.
986 */
987 if (!params->insecure_elasticity)
988 ht->elasticity = 16;
989
990 if (params->locks_mul) 975 if (params->locks_mul)
991 ht->p.locks_mul = roundup_pow_of_two(params->locks_mul); 976 ht->p.locks_mul = roundup_pow_of_two(params->locks_mul);
992 else 977 else
diff --git a/lib/test_bpf.c b/lib/test_bpf.c
index 0362da0b66c3..a0f66280ea50 100644
--- a/lib/test_bpf.c
+++ b/lib/test_bpf.c
@@ -434,6 +434,41 @@ loop:
434 return 0; 434 return 0;
435} 435}
436 436
437static int __bpf_fill_stxdw(struct bpf_test *self, int size)
438{
439 unsigned int len = BPF_MAXINSNS;
440 struct bpf_insn *insn;
441 int i;
442
443 insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
444 if (!insn)
445 return -ENOMEM;
446
447 insn[0] = BPF_ALU32_IMM(BPF_MOV, R0, 1);
448 insn[1] = BPF_ST_MEM(size, R10, -40, 42);
449
450 for (i = 2; i < len - 2; i++)
451 insn[i] = BPF_STX_XADD(size, R10, R0, -40);
452
453 insn[len - 2] = BPF_LDX_MEM(size, R0, R10, -40);
454 insn[len - 1] = BPF_EXIT_INSN();
455
456 self->u.ptr.insns = insn;
457 self->u.ptr.len = len;
458
459 return 0;
460}
461
462static int bpf_fill_stxw(struct bpf_test *self)
463{
464 return __bpf_fill_stxdw(self, BPF_W);
465}
466
467static int bpf_fill_stxdw(struct bpf_test *self)
468{
469 return __bpf_fill_stxdw(self, BPF_DW);
470}
471
437static struct bpf_test tests[] = { 472static struct bpf_test tests[] = {
438 { 473 {
439 "TAX", 474 "TAX",
@@ -4303,6 +4338,41 @@ static struct bpf_test tests[] = {
4303 { { 0, 0x22 } }, 4338 { { 0, 0x22 } },
4304 }, 4339 },
4305 { 4340 {
4341 "STX_XADD_W: Test side-effects, r10: 0x12 + 0x10 = 0x22",
4342 .u.insns_int = {
4343 BPF_ALU64_REG(BPF_MOV, R1, R10),
4344 BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
4345 BPF_ST_MEM(BPF_W, R10, -40, 0x10),
4346 BPF_STX_XADD(BPF_W, R10, R0, -40),
4347 BPF_ALU64_REG(BPF_MOV, R0, R10),
4348 BPF_ALU64_REG(BPF_SUB, R0, R1),
4349 BPF_EXIT_INSN(),
4350 },
4351 INTERNAL,
4352 { },
4353 { { 0, 0 } },
4354 },
4355 {
4356 "STX_XADD_W: Test side-effects, r0: 0x12 + 0x10 = 0x22",
4357 .u.insns_int = {
4358 BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
4359 BPF_ST_MEM(BPF_W, R10, -40, 0x10),
4360 BPF_STX_XADD(BPF_W, R10, R0, -40),
4361 BPF_EXIT_INSN(),
4362 },
4363 INTERNAL,
4364 { },
4365 { { 0, 0x12 } },
4366 },
4367 {
4368 "STX_XADD_W: X + 1 + 1 + 1 + ...",
4369 { },
4370 INTERNAL,
4371 { },
4372 { { 0, 4134 } },
4373 .fill_helper = bpf_fill_stxw,
4374 },
4375 {
4306 "STX_XADD_DW: Test: 0x12 + 0x10 = 0x22", 4376 "STX_XADD_DW: Test: 0x12 + 0x10 = 0x22",
4307 .u.insns_int = { 4377 .u.insns_int = {
4308 BPF_ALU32_IMM(BPF_MOV, R0, 0x12), 4378 BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
@@ -4315,6 +4385,41 @@ static struct bpf_test tests[] = {
4315 { }, 4385 { },
4316 { { 0, 0x22 } }, 4386 { { 0, 0x22 } },
4317 }, 4387 },
4388 {
4389 "STX_XADD_DW: Test side-effects, r10: 0x12 + 0x10 = 0x22",
4390 .u.insns_int = {
4391 BPF_ALU64_REG(BPF_MOV, R1, R10),
4392 BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
4393 BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
4394 BPF_STX_XADD(BPF_DW, R10, R0, -40),
4395 BPF_ALU64_REG(BPF_MOV, R0, R10),
4396 BPF_ALU64_REG(BPF_SUB, R0, R1),
4397 BPF_EXIT_INSN(),
4398 },
4399 INTERNAL,
4400 { },
4401 { { 0, 0 } },
4402 },
4403 {
4404 "STX_XADD_DW: Test side-effects, r0: 0x12 + 0x10 = 0x22",
4405 .u.insns_int = {
4406 BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
4407 BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
4408 BPF_STX_XADD(BPF_DW, R10, R0, -40),
4409 BPF_EXIT_INSN(),
4410 },
4411 INTERNAL,
4412 { },
4413 { { 0, 0x12 } },
4414 },
4415 {
4416 "STX_XADD_DW: X + 1 + 1 + 1 + ...",
4417 { },
4418 INTERNAL,
4419 { },
4420 { { 0, 4134 } },
4421 .fill_helper = bpf_fill_stxdw,
4422 },
4318 /* BPF_JMP | BPF_EXIT */ 4423 /* BPF_JMP | BPF_EXIT */
4319 { 4424 {
4320 "JMP_EXIT", 4425 "JMP_EXIT",
@@ -4656,6 +4761,51 @@ static struct bpf_test tests[] = {
4656 { }, 4761 { },
4657 { { 0, 1 } }, 4762 { { 0, 1 } },
4658 }, 4763 },
4764 {
4765 /* Mainly testing JIT + imm64 here. */
4766 "JMP_JGE_X: ldimm64 test 1",
4767 .u.insns_int = {
4768 BPF_ALU32_IMM(BPF_MOV, R0, 0),
4769 BPF_LD_IMM64(R1, 3),
4770 BPF_LD_IMM64(R2, 2),
4771 BPF_JMP_REG(BPF_JGE, R1, R2, 2),
4772 BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
4773 BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
4774 BPF_EXIT_INSN(),
4775 },
4776 INTERNAL,
4777 { },
4778 { { 0, 0xeeeeeeeeU } },
4779 },
4780 {
4781 "JMP_JGE_X: ldimm64 test 2",
4782 .u.insns_int = {
4783 BPF_ALU32_IMM(BPF_MOV, R0, 0),
4784 BPF_LD_IMM64(R1, 3),
4785 BPF_LD_IMM64(R2, 2),
4786 BPF_JMP_REG(BPF_JGE, R1, R2, 0),
4787 BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
4788 BPF_EXIT_INSN(),
4789 },
4790 INTERNAL,
4791 { },
4792 { { 0, 0xffffffffU } },
4793 },
4794 {
4795 "JMP_JGE_X: ldimm64 test 3",
4796 .u.insns_int = {
4797 BPF_ALU32_IMM(BPF_MOV, R0, 1),
4798 BPF_LD_IMM64(R1, 3),
4799 BPF_LD_IMM64(R2, 2),
4800 BPF_JMP_REG(BPF_JGE, R1, R2, 4),
4801 BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
4802 BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
4803 BPF_EXIT_INSN(),
4804 },
4805 INTERNAL,
4806 { },
4807 { { 0, 1 } },
4808 },
4659 /* BPF_JMP | BPF_JNE | BPF_X */ 4809 /* BPF_JMP | BPF_JNE | BPF_X */
4660 { 4810 {
4661 "JMP_JNE_X: if (3 != 2) return 1", 4811 "JMP_JNE_X: if (3 != 2) return 1",