aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/cipso_ipv4.c7
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/ipv4/ipconfig.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_ftp.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c8
-rw-r--r--net/ipv4/netfilter/arp_tables.c25
-rw-r--r--net/ipv4/netfilter/ip_queue.c7
-rw-r--r--net/ipv4/netfilter/ip_tables.c67
-rw-r--r--net/ipv4/raw.c17
-rw-r--r--net/ipv4/sysctl_net_ipv4.c7
-rw-r--r--net/ipv4/tcp.c11
-rw-r--r--net/ipv4/tcp_cong.c8
-rw-r--r--net/ipv4/tcp_cubic.c6
-rw-r--r--net/ipv4/tcp_htcp.c2
15 files changed, 94 insertions, 79 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index e2077a3aa8c0..6460233407c7 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1307,7 +1307,8 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1307 1307
1308 /* We can't use ip_options_get() directly because it makes a call to 1308 /* We can't use ip_options_get() directly because it makes a call to
1309 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1309 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
1310 * we can't block here. */ 1310 * we won't always have CAP_NET_RAW even though we _always_ want to
1311 * set the IPOPT_CIPSO option. */
1311 opt_len = (buf_len + 3) & ~3; 1312 opt_len = (buf_len + 3) & ~3;
1312 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 1313 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
1313 if (opt == NULL) { 1314 if (opt == NULL) {
@@ -1317,11 +1318,9 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1317 memcpy(opt->__data, buf, buf_len); 1318 memcpy(opt->__data, buf, buf_len);
1318 opt->optlen = opt_len; 1319 opt->optlen = opt_len;
1319 opt->is_data = 1; 1320 opt->is_data = 1;
1321 opt->cipso = sizeof(struct iphdr);
1320 kfree(buf); 1322 kfree(buf);
1321 buf = NULL; 1323 buf = NULL;
1322 ret_val = ip_options_compile(opt, NULL);
1323 if (ret_val != 0)
1324 goto socket_setattr_failure;
1325 1324
1326 sk_inet = inet_sk(sk); 1325 sk_inet = inet_sk(sk);
1327 if (sk_inet->is_icsk) { 1326 if (sk_inet->is_icsk) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 8dabbfc31267..9f02917d6f45 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -443,7 +443,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
443 opt->router_alert = optptr - iph; 443 opt->router_alert = optptr - iph;
444 break; 444 break;
445 case IPOPT_CIPSO: 445 case IPOPT_CIPSO:
446 if (opt->cipso) { 446 if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
447 pp_ptr = optptr; 447 pp_ptr = optptr;
448 goto error; 448 goto error;
449 } 449 }
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index f8ce84759159..955a07abb91d 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -420,7 +420,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
420{ 420{
421 struct arphdr *rarp; 421 struct arphdr *rarp;
422 unsigned char *rarp_ptr; 422 unsigned char *rarp_ptr;
423 unsigned long sip, tip; 423 u32 sip, tip;
424 unsigned char *sha, *tha; /* s for "source", t for "target" */ 424 unsigned char *sha, *tha; /* s for "source", t for "target" */
425 struct ic_device *d; 425 struct ic_device *d;
426 426
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c
index 6d398f10aa91..687c1de1146f 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/ipv4/ipvs/ip_vs_ftp.c
@@ -200,7 +200,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
200 from = n_cp->vaddr; 200 from = n_cp->vaddr;
201 port = n_cp->vport; 201 port = n_cp->vport;
202 sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), 202 sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from),
203 ntohs(port)&255, (ntohs(port)>>8)&255); 203 (ntohs(port)>>8)&255, ntohs(port)&255);
204 buf_len = strlen(buf); 204 buf_len = strlen(buf);
205 205
206 /* 206 /*
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index bfe779e74590..6ff05c3a32e6 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -117,7 +117,7 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip,
117{ 117{
118 tcph->check = 118 tcph->check =
119 ip_vs_check_diff(~oldip, newip, 119 ip_vs_check_diff(~oldip, newip,
120 ip_vs_check_diff(oldport ^ htonl(0xFFFF), 120 ip_vs_check_diff(oldport ^ htons(0xFFFF),
121 newport, tcph->check)); 121 newport, tcph->check));
122} 122}
123 123
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 54aa7603591f..691c8b637b29 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -122,10 +122,10 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip,
122{ 122{
123 uhdr->check = 123 uhdr->check =
124 ip_vs_check_diff(~oldip, newip, 124 ip_vs_check_diff(~oldip, newip,
125 ip_vs_check_diff(oldport ^ htonl(0xFFFF), 125 ip_vs_check_diff(oldport ^ htons(0xFFFF),
126 newport, uhdr->check)); 126 newport, uhdr->check));
127 if (!uhdr->check) 127 if (!uhdr->check)
128 uhdr->check = htonl(0xFFFF); 128 uhdr->check = -1;
129} 129}
130 130
131static int 131static int
@@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb,
173 cp->protocol, 173 cp->protocol,
174 (*pskb)->csum); 174 (*pskb)->csum);
175 if (udph->check == 0) 175 if (udph->check == 0)
176 udph->check = htonl(0xFFFF); 176 udph->check = -1;
177 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", 177 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
178 pp->name, udph->check, 178 pp->name, udph->check,
179 (char*)&(udph->check) - (char*)udph); 179 (char*)&(udph->check) - (char*)udph);
@@ -228,7 +228,7 @@ udp_dnat_handler(struct sk_buff **pskb,
228 cp->protocol, 228 cp->protocol,
229 (*pskb)->csum); 229 (*pskb)->csum);
230 if (udph->check == 0) 230 if (udph->check == 0)
231 udph->check = 0xFFFF; 231 udph->check = -1;
232 (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; 232 (*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
233 } 233 }
234 return 1; 234 return 1;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 0849f1cced13..413c2d0a1f3d 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -466,7 +466,13 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
466 return -EINVAL; 466 return -EINVAL;
467 } 467 }
468 468
469 if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset)
470 return -EINVAL;
471
469 t = arpt_get_target(e); 472 t = arpt_get_target(e);
473 if (e->target_offset + t->u.target_size > e->next_offset)
474 return -EINVAL;
475
470 target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, 476 target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
471 t->u.user.revision), 477 t->u.user.revision),
472 "arpt_%s", t->u.user.name); 478 "arpt_%s", t->u.user.name);
@@ -621,20 +627,18 @@ static int translate_table(const char *name,
621 } 627 }
622 } 628 }
623 629
624 if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
625 duprintf("Looping hook\n");
626 return -ELOOP;
627 }
628
629 /* Finally, each sanity check must pass */ 630 /* Finally, each sanity check must pass */
630 i = 0; 631 i = 0;
631 ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, 632 ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
632 check_entry, name, size, &i); 633 check_entry, name, size, &i);
633 634
634 if (ret != 0) { 635 if (ret != 0)
635 ARPT_ENTRY_ITERATE(entry0, newinfo->size, 636 goto cleanup;
636 cleanup_entry, &i); 637
637 return ret; 638 ret = -ELOOP;
639 if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
640 duprintf("Looping hook\n");
641 goto cleanup;
638 } 642 }
639 643
640 /* And one copy for every other CPU */ 644 /* And one copy for every other CPU */
@@ -643,6 +647,9 @@ static int translate_table(const char *name,
643 memcpy(newinfo->entries[i], entry0, newinfo->size); 647 memcpy(newinfo->entries[i], entry0, newinfo->size);
644 } 648 }
645 649
650 return 0;
651cleanup:
652 ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
646 return ret; 653 return ret;
647} 654}
648 655
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 7edad790478a..97556cc2e4e0 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -351,9 +351,10 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
351 if (v->data_len < sizeof(*user_iph)) 351 if (v->data_len < sizeof(*user_iph))
352 return 0; 352 return 0;
353 diff = v->data_len - e->skb->len; 353 diff = v->data_len - e->skb->len;
354 if (diff < 0) 354 if (diff < 0) {
355 skb_trim(e->skb, v->data_len); 355 if (pskb_trim(e->skb, v->data_len))
356 else if (diff > 0) { 356 return -ENOMEM;
357 } else if (diff > 0) {
357 if (v->data_len > 0xFFFF) 358 if (v->data_len > 0xFFFF)
358 return -EINVAL; 359 return -EINVAL;
359 if (diff > skb_tailroom(e->skb)) { 360 if (diff > skb_tailroom(e->skb)) {
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4b90927619b8..8a455439b128 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -547,12 +547,18 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
547 return -EINVAL; 547 return -EINVAL;
548 } 548 }
549 549
550 if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
551 return -EINVAL;
552
550 j = 0; 553 j = 0;
551 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); 554 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
552 if (ret != 0) 555 if (ret != 0)
553 goto cleanup_matches; 556 goto cleanup_matches;
554 557
555 t = ipt_get_target(e); 558 t = ipt_get_target(e);
559 ret = -EINVAL;
560 if (e->target_offset + t->u.target_size > e->next_offset)
561 goto cleanup_matches;
556 target = try_then_request_module(xt_find_target(AF_INET, 562 target = try_then_request_module(xt_find_target(AF_INET,
557 t->u.user.name, 563 t->u.user.name,
558 t->u.user.revision), 564 t->u.user.revision),
@@ -712,19 +718,17 @@ translate_table(const char *name,
712 } 718 }
713 } 719 }
714 720
715 if (!mark_source_chains(newinfo, valid_hooks, entry0))
716 return -ELOOP;
717
718 /* Finally, each sanity check must pass */ 721 /* Finally, each sanity check must pass */
719 i = 0; 722 i = 0;
720 ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, 723 ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
721 check_entry, name, size, &i); 724 check_entry, name, size, &i);
722 725
723 if (ret != 0) { 726 if (ret != 0)
724 IPT_ENTRY_ITERATE(entry0, newinfo->size, 727 goto cleanup;
725 cleanup_entry, &i); 728
726 return ret; 729 ret = -ELOOP;
727 } 730 if (!mark_source_chains(newinfo, valid_hooks, entry0))
731 goto cleanup;
728 732
729 /* And one copy for every other CPU */ 733 /* And one copy for every other CPU */
730 for_each_possible_cpu(i) { 734 for_each_possible_cpu(i) {
@@ -732,6 +736,9 @@ translate_table(const char *name,
732 memcpy(newinfo->entries[i], entry0, newinfo->size); 736 memcpy(newinfo->entries[i], entry0, newinfo->size);
733 } 737 }
734 738
739 return 0;
740cleanup:
741 IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
735 return ret; 742 return ret;
736} 743}
737 744
@@ -1463,6 +1470,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1463 return -EINVAL; 1470 return -EINVAL;
1464 } 1471 }
1465 1472
1473 if (e->target_offset + sizeof(struct compat_xt_entry_target) >
1474 e->next_offset)
1475 return -EINVAL;
1476
1466 off = 0; 1477 off = 0;
1467 entry_offset = (void *)e - (void *)base; 1478 entry_offset = (void *)e - (void *)base;
1468 j = 0; 1479 j = 0;
@@ -1472,6 +1483,9 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1472 goto cleanup_matches; 1483 goto cleanup_matches;
1473 1484
1474 t = ipt_get_target(e); 1485 t = ipt_get_target(e);
1486 ret = -EINVAL;
1487 if (e->target_offset + t->u.target_size > e->next_offset)
1488 goto cleanup_matches;
1475 target = try_then_request_module(xt_find_target(AF_INET, 1489 target = try_then_request_module(xt_find_target(AF_INET,
1476 t->u.user.name, 1490 t->u.user.name,
1477 t->u.user.revision), 1491 t->u.user.revision),
@@ -1513,7 +1527,7 @@ cleanup_matches:
1513 1527
1514static inline int compat_copy_match_from_user(struct ipt_entry_match *m, 1528static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
1515 void **dstptr, compat_uint_t *size, const char *name, 1529 void **dstptr, compat_uint_t *size, const char *name,
1516 const struct ipt_ip *ip, unsigned int hookmask, int *i) 1530 const struct ipt_ip *ip, unsigned int hookmask)
1517{ 1531{
1518 struct ipt_entry_match *dm; 1532 struct ipt_entry_match *dm;
1519 struct ipt_match *match; 1533 struct ipt_match *match;
@@ -1526,22 +1540,13 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
1526 ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), 1540 ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
1527 name, hookmask, ip->proto, 1541 name, hookmask, ip->proto,
1528 ip->invflags & IPT_INV_PROTO); 1542 ip->invflags & IPT_INV_PROTO);
1529 if (ret) 1543 if (!ret && m->u.kernel.match->checkentry
1530 goto err;
1531
1532 if (m->u.kernel.match->checkentry
1533 && !m->u.kernel.match->checkentry(name, ip, match, dm->data, 1544 && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
1534 hookmask)) { 1545 hookmask)) {
1535 duprintf("ip_tables: check failed for `%s'.\n", 1546 duprintf("ip_tables: check failed for `%s'.\n",
1536 m->u.kernel.match->name); 1547 m->u.kernel.match->name);
1537 ret = -EINVAL; 1548 ret = -EINVAL;
1538 goto err;
1539 } 1549 }
1540 (*i)++;
1541 return 0;
1542
1543err:
1544 module_put(m->u.kernel.match->me);
1545 return ret; 1550 return ret;
1546} 1551}
1547 1552
@@ -1553,19 +1558,18 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
1553 struct ipt_target *target; 1558 struct ipt_target *target;
1554 struct ipt_entry *de; 1559 struct ipt_entry *de;
1555 unsigned int origsize; 1560 unsigned int origsize;
1556 int ret, h, j; 1561 int ret, h;
1557 1562
1558 ret = 0; 1563 ret = 0;
1559 origsize = *size; 1564 origsize = *size;
1560 de = (struct ipt_entry *)*dstptr; 1565 de = (struct ipt_entry *)*dstptr;
1561 memcpy(de, e, sizeof(struct ipt_entry)); 1566 memcpy(de, e, sizeof(struct ipt_entry));
1562 1567
1563 j = 0;
1564 *dstptr += sizeof(struct compat_ipt_entry); 1568 *dstptr += sizeof(struct compat_ipt_entry);
1565 ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, 1569 ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
1566 name, &de->ip, de->comefrom, &j); 1570 name, &de->ip, de->comefrom);
1567 if (ret) 1571 if (ret)
1568 goto cleanup_matches; 1572 goto err;
1569 de->target_offset = e->target_offset - (origsize - *size); 1573 de->target_offset = e->target_offset - (origsize - *size);
1570 t = ipt_get_target(e); 1574 t = ipt_get_target(e);
1571 target = t->u.kernel.target; 1575 target = t->u.kernel.target;
@@ -1599,12 +1603,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
1599 goto err; 1603 goto err;
1600 } 1604 }
1601 ret = 0; 1605 ret = 0;
1602 return ret;
1603
1604err: 1606err:
1605 module_put(t->u.kernel.target->me);
1606cleanup_matches:
1607 IPT_MATCH_ITERATE(e, cleanup_match, &j);
1608 return ret; 1607 return ret;
1609} 1608}
1610 1609
@@ -1618,7 +1617,7 @@ translate_compat_table(const char *name,
1618 unsigned int *hook_entries, 1617 unsigned int *hook_entries,
1619 unsigned int *underflows) 1618 unsigned int *underflows)
1620{ 1619{
1621 unsigned int i; 1620 unsigned int i, j;
1622 struct xt_table_info *newinfo, *info; 1621 struct xt_table_info *newinfo, *info;
1623 void *pos, *entry0, *entry1; 1622 void *pos, *entry0, *entry1;
1624 unsigned int size; 1623 unsigned int size;
@@ -1636,21 +1635,21 @@ translate_compat_table(const char *name,
1636 } 1635 }
1637 1636
1638 duprintf("translate_compat_table: size %u\n", info->size); 1637 duprintf("translate_compat_table: size %u\n", info->size);
1639 i = 0; 1638 j = 0;
1640 xt_compat_lock(AF_INET); 1639 xt_compat_lock(AF_INET);
1641 /* Walk through entries, checking offsets. */ 1640 /* Walk through entries, checking offsets. */
1642 ret = IPT_ENTRY_ITERATE(entry0, total_size, 1641 ret = IPT_ENTRY_ITERATE(entry0, total_size,
1643 check_compat_entry_size_and_hooks, 1642 check_compat_entry_size_and_hooks,
1644 info, &size, entry0, 1643 info, &size, entry0,
1645 entry0 + total_size, 1644 entry0 + total_size,
1646 hook_entries, underflows, &i, name); 1645 hook_entries, underflows, &j, name);
1647 if (ret != 0) 1646 if (ret != 0)
1648 goto out_unlock; 1647 goto out_unlock;
1649 1648
1650 ret = -EINVAL; 1649 ret = -EINVAL;
1651 if (i != number) { 1650 if (j != number) {
1652 duprintf("translate_compat_table: %u not %u entries\n", 1651 duprintf("translate_compat_table: %u not %u entries\n",
1653 i, number); 1652 j, number);
1654 goto out_unlock; 1653 goto out_unlock;
1655 } 1654 }
1656 1655
@@ -1709,8 +1708,10 @@ translate_compat_table(const char *name,
1709free_newinfo: 1708free_newinfo:
1710 xt_free_table_info(newinfo); 1709 xt_free_table_info(newinfo);
1711out: 1710out:
1711 IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
1712 return ret; 1712 return ret;
1713out_unlock: 1713out_unlock:
1714 compat_flush_offsets();
1714 xt_compat_unlock(AF_INET); 1715 xt_compat_unlock(AF_INET);
1715 goto out; 1716 goto out;
1716} 1717}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b430cf2a4f66..5c31dead2bdc 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -329,7 +329,7 @@ error:
329 return err; 329 return err;
330} 330}
331 331
332static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 332static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
333{ 333{
334 struct iovec *iov; 334 struct iovec *iov;
335 u8 __user *type = NULL; 335 u8 __user *type = NULL;
@@ -338,7 +338,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
338 unsigned int i; 338 unsigned int i;
339 339
340 if (!msg->msg_iov) 340 if (!msg->msg_iov)
341 return; 341 return 0;
342 342
343 for (i = 0; i < msg->msg_iovlen; i++) { 343 for (i = 0; i < msg->msg_iovlen; i++) {
344 iov = &msg->msg_iov[i]; 344 iov = &msg->msg_iov[i];
@@ -360,8 +360,9 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
360 code = iov->iov_base; 360 code = iov->iov_base;
361 361
362 if (type && code) { 362 if (type && code) {
363 get_user(fl->fl_icmp_type, type); 363 if (get_user(fl->fl_icmp_type, type) ||
364 get_user(fl->fl_icmp_code, code); 364 get_user(fl->fl_icmp_code, code))
365 return -EFAULT;
365 probed = 1; 366 probed = 1;
366 } 367 }
367 break; 368 break;
@@ -372,6 +373,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
372 if (probed) 373 if (probed)
373 break; 374 break;
374 } 375 }
376 return 0;
375} 377}
376 378
377static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 379static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
@@ -480,8 +482,11 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
480 .proto = inet->hdrincl ? IPPROTO_RAW : 482 .proto = inet->hdrincl ? IPPROTO_RAW :
481 sk->sk_protocol, 483 sk->sk_protocol,
482 }; 484 };
483 if (!inet->hdrincl) 485 if (!inet->hdrincl) {
484 raw_probe_proto_opt(&fl, msg); 486 err = raw_probe_proto_opt(&fl, msg);
487 if (err)
488 goto done;
489 }
485 490
486 security_sk_classify_flow(sk, &fl); 491 security_sk_classify_flow(sk, &fl);
487 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); 492 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index e82a5be894b5..15061b314411 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -129,13 +129,6 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
129 return ret; 129 return ret;
130} 130}
131 131
132static int __init tcp_congestion_default(void)
133{
134 return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
135}
136
137late_initcall(tcp_congestion_default);
138
139ctl_table ipv4_table[] = { 132ctl_table ipv4_table[] = {
140 { 133 {
141 .ctl_name = NET_IPV4_TCP_TIMESTAMPS, 134 .ctl_name = NET_IPV4_TCP_TIMESTAMPS,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 66e9a729f6df..c05e8edaf544 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2270,7 +2270,7 @@ void __init tcp_init(void)
2270 thash_entries, 2270 thash_entries,
2271 (num_physpages >= 128 * 1024) ? 2271 (num_physpages >= 128 * 1024) ?
2272 13 : 15, 2272 13 : 15,
2273 HASH_HIGHMEM, 2273 0,
2274 &tcp_hashinfo.ehash_size, 2274 &tcp_hashinfo.ehash_size,
2275 NULL, 2275 NULL,
2276 0); 2276 0);
@@ -2286,7 +2286,7 @@ void __init tcp_init(void)
2286 tcp_hashinfo.ehash_size, 2286 tcp_hashinfo.ehash_size,
2287 (num_physpages >= 128 * 1024) ? 2287 (num_physpages >= 128 * 1024) ?
2288 13 : 15, 2288 13 : 15,
2289 HASH_HIGHMEM, 2289 0,
2290 &tcp_hashinfo.bhash_size, 2290 &tcp_hashinfo.bhash_size,
2291 NULL, 2291 NULL,
2292 64 * 1024); 2292 64 * 1024);
@@ -2316,9 +2316,10 @@ void __init tcp_init(void)
2316 sysctl_max_syn_backlog = 128; 2316 sysctl_max_syn_backlog = 128;
2317 } 2317 }
2318 2318
2319 sysctl_tcp_mem[0] = 768 << order; 2319 /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */
2320 sysctl_tcp_mem[1] = 1024 << order; 2320 sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order;
2321 sysctl_tcp_mem[2] = 1536 << order; 2321 sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3;
2322 sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
2322 2323
2323 limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); 2324 limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
2324 max_share = min(4UL*1024*1024, limit); 2325 max_share = min(4UL*1024*1024, limit);
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index af0aca1e6be6..1e2982f4acd4 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -131,6 +131,14 @@ int tcp_set_default_congestion_control(const char *name)
131 return ret; 131 return ret;
132} 132}
133 133
134/* Set default value from kernel configuration at bootup */
135static int __init tcp_congestion_default(void)
136{
137 return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
138}
139late_initcall(tcp_congestion_default);
140
141
134/* Get current default congestion control */ 142/* Get current default congestion control */
135void tcp_get_default_congestion_control(char *name) 143void tcp_get_default_congestion_control(char *name)
136{ 144{
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index a60ef38d75c6..6ad184802266 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -190,7 +190,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
190 */ 190 */
191 191
192 /* change the unit from HZ to bictcp_HZ */ 192 /* change the unit from HZ to bictcp_HZ */
193 t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start) 193 t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start)
194 << BICTCP_HZ) / HZ; 194 << BICTCP_HZ) / HZ;
195 195
196 if (t < ca->bic_K) /* t - K */ 196 if (t < ca->bic_K) /* t - K */
@@ -259,7 +259,7 @@ static inline void measure_delay(struct sock *sk)
259 (s32)(tcp_time_stamp - ca->epoch_start) < HZ) 259 (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
260 return; 260 return;
261 261
262 delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr; 262 delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3;
263 if (delay == 0) 263 if (delay == 0)
264 delay = 1; 264 delay = 1;
265 265
@@ -366,7 +366,7 @@ static int __init cubictcp_register(void)
366 366
367 beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); 367 beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta);
368 368
369 cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */ 369 cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */
370 370
371 /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 371 /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
372 * so K = cubic_root( (wmax-cwnd)*rtt/c ) 372 * so K = cubic_root( (wmax-cwnd)*rtt/c )
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index 682e7d5b6f2f..283be3cb4667 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -23,7 +23,7 @@ module_param(use_bandwidth_switch, int, 0644);
23MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); 23MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher");
24 24
25struct htcp { 25struct htcp {
26 u16 alpha; /* Fixed point arith, << 7 */ 26 u32 alpha; /* Fixed point arith, << 7 */
27 u8 beta; /* Fixed point arith, << 7 */ 27 u8 beta; /* Fixed point arith, << 7 */
28 u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ 28 u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */
29 u32 last_cong; /* Time since last congestion event end */ 29 u32 last_cong; /* Time since last congestion event end */