July 6, 2014

ipsec local routing bypass

Suppose that you have a ipsec site-to-site network as follows:

On local: from 10.1.0.0/16 to 0.0.0.0/0  goes to remote ipsec
On remote: from 0.0.0.0/0 to 10.1.0.0/16 goes to ipsec

Now on local you have a subnet 10.1.1.0/24 that you want to talk to. For example, you local interface eth1 has 10.1.1.1, and there is another computer on your network 10.1.1.2. Now if you want to ping 10.1.1.2 it would not work, because the traffic is captured by the ipsec policy (use "ip xfrm policy" to show it) and directed to ipsec tunnel.

To add local route bypass, use this:
ip xfrm policy add dir in src 10.1.1.0/24 dst 10.1.1.0/24
ip xfrm policy add dir out src 10.1.1.0/24 dst 10.1.1.0/24

run this after your ipsec tunnel is up. Then you should be able to ping 10.1.1.2.

Note when I add polices directly use "setkey" it did not work for me.

Looks like StrongSwan can do this using config file section called "shunt" policies. Needs to try this.

July 3, 2014

sfdisk tips

sfdisk can be used to list partition information and alter partition tables

cat /proc/partitions to see the list of kernel recognized drivers and partitions

sfdisk -l : list information

sfdisk -l -u M : list information using MiB as unit. 

sfdisk -l -u S : List information using sector (512 bytes) as unit.

Example:
 sudo sfdisk -l /dev/sdc -u M

Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = mebibytes of 1048576 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start   End    MiB    #blocks   Id  System
/dev/sdc1   *     1   7806   7806    7993344   83  Linux
/dev/sdc2      7807+  8190    384-    392193    5  Extended
/dev/sdc3         0      -      0          0    0  Empty
/dev/sdc4         0      -      0          0    0  Empty
/dev/sdc5      7808   8190    383     392192   82  Linux swap / Solaris

Notice "7807+" and "384-" means that the numbers are not a multiple of MiB. Therefore that partition is not MiB aligned. For Extended partition, that is OK, but for real data-holding partitions, you may want them to be MiB aligned.

This is the list by sector results:
sudo sfdisk -l /dev/sdc -u S

Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = sectors of 512 bytes, counting from 0

   Device Boot    Start       End   #sectors  Id  System
/dev/sdc1   *      2048  15988735   15986688  83  Linux
/dev/sdc2      15990782  16775167     784386   5  Extended
/dev/sdc3             0         -          0   0  Empty
/dev/sdc4             0         -          0   0  Empty
/dev/sdc5      15990784  16775167     784384  82  Linux swap / Solaris

Notice now there is no +/- anymore, and start/end are in sectors. This will give you exact layout of the partitions.

Write partitions:
sfdisk takes two kinds of formats as input to write partitions: the "manual" format as documented in the man page, and the "dump" format.

Use "-d" to dump the current partition table.

 sudo sfdisk -d /dev/sdc
# partition table of /dev/sdc
unit: sectors

/dev/sdc1 : start=     2048, size= 15986688, Id=83, bootable
/dev/sdc2 : start= 15990782, size=   784386, Id= 5
/dev/sdc3 : start=        0, size=        0, Id= 0
/dev/sdc4 : start=        0, size=        0, Id= 0
/dev/sdc5 : start= 15990784, size=   784384, Id=82

Now you can edit this file, and then feed it back to change partitions using command "sfdisk -d /dev/sdc < part.txt", supposing that you wrote the above text to "part.txt" file.

Now some explanation of the "dump" format:

1. Empty lines are ignored
2. # and things after it is ignored (for that line)
3. "unit: sectors" is recognized as a valid command to set unit to sectors
4. Each partition line starts with the partition name, which is ignored. Then ":", then  multiplle "variable-name=value" separated by ",". "bootable" is special because it is a boolean value.
5. All values have to be present. No auto calculation as in "manual" mode.

Partition Alignment
When I tried to start partitioning on the 2nd cylinder instead of the first,  I ran into issues. The command was:

sfdisk /dev/sdb -H 16 -S 63 <<EOF
1,159,83
,4096,82
,,83
;

EOF

My 80GB disk does not have a multiple of 2048 sectors, because the total number of sectors is a multiple of 63, which is the typical sectors per track. So to make my partition aligned at least to 4K, I used head of 16, which gives me the cylinder size of 63*16*512bytes=63*8KiB, so my cylinder is 4KiB aligned.

The above command will produce the following error:
sfdisk: Warning: given size (4096) exceeds max allowable size (1)
sfdisk: bad input

I was very puzzled. After compiling sfdisk from source code and adding debug statements in it, I finally found out the reason: sfdisk is trying to fit the 2nd partition in the first free cylinder because it think it is free! Well it is free except for the MBR in the first sector, but I don't want my 2nd partition to there. How do we tell sfdisk that? Here comes the "undocumented dangerous option" "--in-order". If you specify the "--in-order", sfdisk will work as you intended it to.

OR, you could manually specify the start address of each partition.

So the final working command is:
sfdisk /dev/sdb --in-order -H 16 -S 63 <<EOF
1,159,83
,4096,82
,,83
;
EOF


At last, you can use "hdparm -i" to list harddrive info, including number of LBA sectors. However, this may not work on some disks. 

July 2, 2014

Understand fdisk output


Disk /dev/hdb: 64 heads, 63 sectors, 621 cylinders
Units = cylinders of 4032 * 512 bytes
 
   Device Boot    Start       End    Blocks   Id  System
/dev/hdb1   *         1       184    370912+  83  Linux
/dev/hdb2           185       368    370944   83  Linux
/dev/hdb3           369       552    370944   83  Linux
/dev/hdb4           553       621    139104   82  Linux swap

Sector size: 512 bytes

64 Heads: there are 64/2=32 platters in the disk, each platter has 2 heads. Think head as a surface.

63 sectors: Each head is divided in to 63 sectors

621 cylinders: There are 621 of concentric tracks/cylinders on each head. Each track has 63 sectors as indicated above. 

A cylinder is a vertical slice of a track on all heads. Cylinder size = #Heads * #sectors * 512 = 64*63*512 = 4032*512 = 2064384 bytes

Disk are allocated from low cylinders to high cylinders. 

Start/End unit is cylinder. 

Block size is 1024 bytes. 

Blocks per cylinder is 2064384/1024 = 2016

The "+" sign in "370912+" means the number 3780912 is not accurate. The actual blocks should be a little more. To calculate the actual one, just do 370912/2016=183.98, and then rounded it up to get 184. So the first partition has 184 cylinders.

Another example:
Disk /dev/sda: 250.0 GB, 250059350016 bytes
64 heads, 32 sectors/track, 238475 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1          81   82928   83  Linux
/dev/sda2              82        2082   2049024    83  Linux
/dev/sda3            2083      238475   242066432   83  Linux

Cylinder size = 64*32*512=1048576 (1MB)
Blocks per cylinder = 1MB/1024=1024


July 1, 2014

Linux USB sysfs device naming scheme

In Linux dmesg, you may see something like this:

usb 1-1.1: new high speed USB device using musb-hdrc and address 8
usb 1-1.1: New USB device found, idVendor=05e3, idProduct=0608
usb 1-1.1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
usb 1-1.1: Product: USB2.0 Hub
hub 1-1.1:1.0: USB hub found

The naming scheme is like this:

root_hub-hub_port.hub_port.hub_port(...):config.interface

So 1-1.1:1.0 means:

Device connected to Root Hub 1, Port 1 which has another hub connected to it, Port1. Then Config 1, and interface 0.