1. 07 8月, 2008 1 次提交
  2. 06 8月, 2008 2 次提交
  3. 04 8月, 2008 1 次提交
  4. 01 8月, 2008 3 次提交
  5. 31 7月, 2008 2 次提交
  6. 30 7月, 2008 1 次提交
  7. 28 7月, 2008 1 次提交
    • A
      missing bits of net-namespace / sysctl · eeb61f71
      Al Viro 提交于
      Piss-poor sysctl registration API strikes again, film at 11...
      
      What we really need is _pathname_ required to be present in already
      registered table, so that kernel could warn about bad order.  That's the
      next target for sysctl stuff (and generally saner and more explicit
      order of initialization of ipv[46] internals wouldn't hurt either).
      
      For the time being, here are full fixups required by ..._rotable()
      stuff; we make per-net sysctl sets descendents of "ro" one and make sure
      that sufficient skeleton is there before we start registering per-net
      sysctls.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      eeb61f71
  8. 27 7月, 2008 6 次提交
  9. 26 7月, 2008 3 次提交
  10. 25 7月, 2008 1 次提交
  11. 24 7月, 2008 2 次提交
    • P
    • D
      tcp: Clear probes_out more aggressively in tcp_ack(). · 4b53fb67
      David S. Miller 提交于
      This is based upon an excellent bug report from Eric Dumazet.
      
      tcp_ack() should clear ->icsk_probes_out even if there are packets
      outstanding.  Otherwise if we get a sequence of ACKs while we do have
      packets outstanding over and over again, we'll never clear the
      probes_out value and eventually think the connection is too sick and
      we'll reset it.
      
      This appears to be some "optimization" added to tcp_ack() in the 2.4.x
      timeframe.  In 2.2.x, probes_out is pretty much always cleared by
      tcp_ack().
      
      Here is Eric's original report:
      
      ----------------------------------------
      Apparently, we can in some situations reset TCP connections in a couple of seconds when some frames are lost.
      
      In order to reproduce the problem, please try the following program on linux-2.6.25.*
      
      Setup some iptables rules to allow two frames per second sent on loopback interface to tcp destination port 12000
      
      iptables -N SLOWLO
      iptables -A SLOWLO -m hashlimit --hashlimit 2 --hashlimit-burst 1 --hashlimit-mode dstip --hashlimit-name slow2 -j ACCEPT
      iptables -A SLOWLO -j DROP
      
      iptables -A OUTPUT -o lo -p tcp --dport 12000 -j SLOWLO
      
      Then run the attached program and see the output :
      
      # ./loop
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,200ms,1)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,200ms,3)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,200ms,5)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,200ms,7)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,200ms,9)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,200ms,11)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,201ms,13)
      State      Recv-Q Send-Q                                  Local Address:Port                                    Peer Address:Port
      ESTAB      0      40                                          127.0.0.1:54455                                      127.0.0.1:12000  timer:(persist,188ms,15)
      write(): Connection timed out
      wrote 890 bytes but was interrupted after 9 seconds
      ESTAB      0      0                 127.0.0.1:12000            127.0.0.1:54455
      Exiting read() because no data available (4000 ms timeout).
      read 860 bytes
      
      While this tcp session makes progress (sending frames with 50 bytes of payload, every 500ms), linux tcp stack decides to reset it, when tcp_retries 2 is reached (default value : 15)
      
      tcpdump :
      
      15:30:28.856695 IP 127.0.0.1.56554 > 127.0.0.1.12000: S 33788768:33788768(0) win 32792 <mss 16396,nop,nop,sackOK,nop,wscale 7>
      15:30:28.856711 IP 127.0.0.1.12000 > 127.0.0.1.56554: S 33899253:33899253(0) ack 33788769 win 32792 <mss 16396,nop,nop,sackOK,nop,wscale 7>
      15:30:29.356947 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 1:61(60) ack 1 win 257
      15:30:29.356966 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 61 win 257
      15:30:29.866415 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 61:111(50) ack 1 win 257
      15:30:29.866427 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 111 win 257
      15:30:30.366516 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 111:161(50) ack 1 win 257
      15:30:30.366527 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 161 win 257
      15:30:30.876196 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 161:211(50) ack 1 win 257
      15:30:30.876207 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 211 win 257
      15:30:31.376282 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 211:261(50) ack 1 win 257
      15:30:31.376290 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 261 win 257
      15:30:31.885619 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 261:311(50) ack 1 win 257
      15:30:31.885631 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 311 win 257
      15:30:32.385705 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 311:361(50) ack 1 win 257
      15:30:32.385715 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 361 win 257
      15:30:32.895249 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 361:411(50) ack 1 win 257
      15:30:32.895266 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 411 win 257
      15:30:33.395341 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 411:461(50) ack 1 win 257
      15:30:33.395351 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 461 win 257
      15:30:33.918085 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 461:511(50) ack 1 win 257
      15:30:33.918096 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 511 win 257
      15:30:34.418163 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 511:561(50) ack 1 win 257
      15:30:34.418172 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 561 win 257
      15:30:34.927685 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 561:611(50) ack 1 win 257
      15:30:34.927698 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 611 win 257
      15:30:35.427757 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 611:661(50) ack 1 win 257
      15:30:35.427766 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 661 win 257
      15:30:35.937359 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 661:711(50) ack 1 win 257
      15:30:35.937376 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 711 win 257
      15:30:36.437451 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 711:761(50) ack 1 win 257
      15:30:36.437464 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 761 win 257
      15:30:36.947022 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 761:811(50) ack 1 win 257
      15:30:36.947039 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 811 win 257
      15:30:37.447135 IP 127.0.0.1.56554 > 127.0.0.1.12000: P 811:861(50) ack 1 win 257
      15:30:37.447203 IP 127.0.0.1.12000 > 127.0.0.1.56554: . ack 861 win 257
      15:30:41.448171 IP 127.0.0.1.12000 > 127.0.0.1.56554: F 1:1(0) ack 861 win 257
      15:30:41.448189 IP 127.0.0.1.56554 > 127.0.0.1.12000: R 33789629:33789629(0) win 0
      
      Source of program :
      
      /*
       * small producer/consumer program.
       * setup a listener on 127.0.0.1:12000
       * Forks a child
       *   child connect to 127.0.0.1, and sends 10 bytes on this tcp socket every 100 ms
       * Father accepts connection, and read all data
       */
      #include <sys/types.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <unistd.h>
      #include <stdio.h>
      #include <time.h>
      #include <sys/poll.h>
      
      int port = 12000;
      char buffer[4096];
      int main(int argc, char *argv[])
      {
              int lfd = socket(AF_INET, SOCK_STREAM, 0);
              struct sockaddr_in socket_address;
              time_t t0, t1;
              int on = 1, sfd, res;
              unsigned long total = 0;
              socklen_t alen = sizeof(socket_address);
              pid_t pid;
      
              time(&t0);
              socket_address.sin_family = AF_INET;
              socket_address.sin_port = htons(port);
              socket_address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
      
              if (lfd == -1) {
                      perror("socket()");
                      return 1;
              }
              setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
              if (bind(lfd, (struct sockaddr *)&socket_address, sizeof(socket_address)) == -1) {
                      perror("bind");
                      close(lfd);
                      return 1;
              }
              if (listen(lfd, 1) == -1) {
                      perror("listen()");
                      close(lfd);
                      return 1;
              }
              pid = fork();
              if (pid == 0) {
                      int i, cfd = socket(AF_INET, SOCK_STREAM, 0);
                      close(lfd);
                      if (connect(cfd, (struct sockaddr *)&socket_address, sizeof(socket_address)) == -1) {
                              perror("connect()");
                              return 1;
                              }
                      for (i = 0 ; ;) {
                              res = write(cfd, "blablabla\n", 10);
                              if (res > 0) total += res;
                              else if (res == -1) {
                                      perror("write()");
                                      break;
                              } else break;
                              usleep(100000);
                              if (++i == 10) {
                                      system("ss -on dst 127.0.0.1:12000");
                                      i = 0;
                              }
                      }
                      time(&t1);
                      fprintf(stderr, "wrote %lu bytes but was interrupted after %g seconds\n", total, difftime(t1, t0));
                      system("ss -on | grep 127.0.0.1:12000");
                      close(cfd);
                      return 0;
              }
              sfd = accept(lfd, (struct sockaddr *)&socket_address, &alen);
              if (sfd == -1) {
                      perror("accept");
                      return 1;
              }
              close(lfd);
              while (1) {
                      struct pollfd pfd[1];
                      pfd[0].fd = sfd;
                      pfd[0].events = POLLIN;
                      if (poll(pfd, 1, 4000) == 0) {
                              fprintf(stderr, "Exiting read() because no data available (4000 ms timeout).\n");
                              break;
                      }
                      res = read(sfd, buffer, sizeof(buffer));
                      if (res > 0) total += res;
                      else if (res == 0) break;
                      else perror("read()");
              }
              fprintf(stderr, "read %lu bytes\n", total);
              close(sfd);
              return 0;
      }
      ----------------------------------------
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4b53fb67
  12. 22 7月, 2008 5 次提交
  13. 20 7月, 2008 1 次提交
  14. 19 7月, 2008 6 次提交
    • D
      tcp: fix kernel panic with listening_get_next · bdccc4ca
      Daniel Lezcano 提交于
      # BUG: unable to handle kernel NULL pointer dereference at
      0000000000000038
      IP: [<ffffffff821ed01e>] listening_get_next+0x50/0x1b3
      PGD 11e4b9067 PUD 11d16c067 PMD 0
      Oops: 0000 [1] SMP
      last sysfs file: /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_map
      CPU 3
      Modules linked in: bridge ipv6 button battery ac loop dm_mod tg3 ext3
      jbd edd fan thermal processor thermal_sys hwmon sg sata_svw libata dock
      serverworks sd_mod scsi_mod ide_disk ide_core [last unloaded: freq_table]
      Pid: 3368, comm: slpd Not tainted 2.6.26-rc2-mm1-lxc4 #1
      RIP: 0010:[<ffffffff821ed01e>] [<ffffffff821ed01e>]
      listening_get_next+0x50/0x1b3
      RSP: 0018:ffff81011e1fbe18 EFLAGS: 00010246
      RAX: 0000000000000000 RBX: ffff8100be0ad3c0 RCX: ffff8100619f50c0
      RDX: ffffffff82475be0 RSI: ffff81011d9ae6c0 RDI: ffff8100be0ad508
      RBP: ffff81011f4f1240 R08: 00000000ffffffff R09: ffff8101185b6780
      R10: 000000000000002d R11: ffffffff820fdbfa R12: ffff8100be0ad3c8
      R13: ffff8100be0ad6a0 R14: ffff8100be0ad3c0 R15: ffffffff825b8ce0
      FS: 00007f6a0ebd16d0(0000) GS:ffff81011f424540(0000)
      knlGS:0000000000000000
      CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
      CR2: 0000000000000038 CR3: 000000011dc20000 CR4: 00000000000006e0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      Process slpd (pid: 3368, threadinfo ffff81011e1fa000, task
      ffff81011f4b8660)
      Stack: 00000000000002ee ffff81011f5a57c0 ffff81011f4f1240
      ffff81011e1fbe90
      0000000000001000 0000000000000000 00007fff16bf2590 ffffffff821ed9c8
      ffff81011f5a57c0 ffff81011d9ae6c0 000000000000041a ffffffff820b0abd
      Call Trace:
      [<ffffffff821ed9c8>] ? tcp_seq_next+0x34/0x7e
      [<ffffffff820b0abd>] ? seq_read+0x1aa/0x29d
      [<ffffffff820d21b4>] ? proc_reg_read+0x73/0x8e
      [<ffffffff8209769c>] ? vfs_read+0xaa/0x152
      [<ffffffff82097a7d>] ? sys_read+0x45/0x6e
      [<ffffffff8200bd2b>] ? system_call_after_swapgs+0x7b/0x80
      
      
      Code: 31 a9 25 00 e9 b5 00 00 00 ff 45 20 83 7d 0c 01 75 79 4c 8b 75 10
      48 8b 0e eb 1d 48 8b 51 20 0f b7 45 08 39 02 75 0e 48 8b 41 28 <4c> 39
      78 38 0f 84 93 00 00 00 48 8b 09 48 85 c9 75 de 8b 55 1c
      RIP [<ffffffff821ed01e>] listening_get_next+0x50/0x1b3
      RSP <ffff81011e1fbe18>
      CR2: 0000000000000038
      
      This kernel panic appears with CONFIG_NET_NS=y.
      
      How to reproduce ?
      
          On the buggy host (host A)
             * ip addr add 1.2.3.4/24 dev eth0
      
          On a remote host (host B)
             * ip addr add 1.2.3.5/24 dev eth0
             * iptables -A INPUT -p tcp -s 1.2.3.4 -j DROP
             * ssh 1.2.3.4
      
          On host A:
             * netstat -ta or cat /proc/net/tcp
      
      This bug happens when reading /proc/net/tcp[6] when there is a req_sock
      at the SYN_RECV state.
      
      When a SYN is received the minisock is created and the sk field is set to
      NULL. In the listening_get_next function, we try to look at the field 
      req->sk->sk_net.
      
      When looking at how to fix this bug, I noticed that is useless to do
      the check for the minisock belonging to the namespace. A minisock belongs
      to a listen point and this one is per namespace, so when browsing the
      minisock they are always per namespace.
      Signed-off-by: NDaniel Lezcano <dlezcano@fr.ibm.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      bdccc4ca
    • A
      tcp: Remove redundant checks when setting eff_sacks · 4389dded
      Adam Langley 提交于
      Remove redundant checks when setting eff_sacks and make the number of SACKs a
      compile time constant. Now that the options code knows how many SACK blocks can
      fit in the header, we don't need to have the SACK code guessing at it.
      Signed-off-by: NAdam Langley <agl@imperialviolet.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4389dded
    • A
      tcp: options clean up · 33ad798c
      Adam Langley 提交于
      This should fix the following bugs:
        * Connections with MD5 signatures produce invalid packets whenever SACK
          options are included
        * MD5 signatures are counted twice in the MSS calculations
      
      Behaviour changes:
        * A SYN with MD5 + SACK + TS elicits a SYNACK with MD5 + SACK
      
          This is because we can't fit any SACK blocks in a packet with MD5 + TS
          options. There was discussion about disabling SACK rather than TS in
          order to fit in better with old, buggy kernels, but that was deemed to
          be unnecessary.
      
        * SYNs with MD5 don't include a TS option
      
          See above.
      
      Additionally, it removes a bunch of duplicated logic for calculating options,
      which should help avoid these sort of issues in the future.
      Signed-off-by: NAdam Langley <agl@imperialviolet.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      33ad798c
    • A
      tcp: Fix MD5 signatures for non-linear skbs · 49a72dfb
      Adam Langley 提交于
      Currently, the MD5 code assumes that the SKBs are linear and, in the case
      that they aren't, happily goes off and hashes off the end of the SKB and
      into random memory.
      
      Reported by Stephen Hemminger in [1]. Advice thanks to Stephen and Evgeniy
      Polyakov. Also includes a couple of missed route_caps from Stephen's patch
      in [2].
      
      [1] http://marc.info/?l=linux-netdev&m=121445989106145&w=2
      [2] http://marc.info/?l=linux-netdev&m=121459157816964&w=2Signed-off-by: NAdam Langley <agl@imperialviolet.org>
      Acked-by: NStephen Hemminger <shemminger@vyatta.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      49a72dfb
    • H
    • S
      tcp: RTT metrics scaling · c1e20f7c
      Stephen Hemminger 提交于
      Some of the metrics (RTT, RTTVAR and RTAX_RTO_MIN) are stored in
      kernel units (jiffies) and this leaks out through the netlink API to
      user space where the units for jiffies are unknown.
      
      This patches changes the kernel to convert to/from milliseconds. This
      changes the ABI, but milliseconds seemed like the most natural unit
      for these parameters.  Values available via syscall in
      /proc/net/rt_cache and netlink will be in milliseconds.
      Signed-off-by: NStephen Hemminger <shemminger@vyatta.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c1e20f7c
  15. 18 7月, 2008 5 次提交