搭 Caltrain 到 San Francisco (舊金山)

大概十多年前來美的時候,當時同事的朋友就帶我們來看 Caltrain 了,印像中當時是看 Caltrain 呼嘯而過。後來出差來美國,一來離 Caltrain 很遠,二來就算要開車來也是要幾十公里,最後是 Caltrain 只到舊金山,常常去的地方不止舊金山,所以也沒有什麼機會搭 Caltrain。

Read more »

Change Ubuntu Cloud Image Size

Ubuntu Cloud Image Size 似乎各個版本的特性不太一樣, 而且似乎也要用不同的方式修改 Image size

Read more »

Office 2016 註冊後還是一直出現要求註冊(啟用)的視窗

這個是預裝 Windows 和 Office 2016 但是沒有買 Office 2016 License 的電腦才會發生.

即使 Uninstall 預裝的 Office , 再次安裝合法註冊 Office 之後, 仍然一直會出現這個視窗, 雖然可以關掉但是不影響使用

Read more »

minecraft 如何用 Google Drive 同步到多台電腦

這個同題很簡單, 就建立目錄 Link 就好了

1. 開 Windows 檔案總管到

%appdata%\.minecraft

這樣就會指到 .minecraft 的目錄, 一般是在 C:\Users\[USERNAME]\AppData\Roaming\.minecraft

2. 將 .minecraft 備份, 然後移(move)到 Google driver 下, 建一個目錄叫 Minecraft, 接下來 .minecraft 搬進去取名叫 data (或是其他你高興的字樣, 我用 data 做範例)
假設你的 Google Driver 在 D:\GoogleDrive\
那 .minecraft 新的目錄就在 D:\GoogleDrive\Minecraft\data

3. 執行有 administrator 權限的 cmd.exe, 然後輸入以下指令, 記得要將 [USERNAME] 換成 windows 使用者的名稱

mklink /D "C:\Users\[USERNAME\\AppData\Roaming\.minecraft" "D:\GoogleDrive\Minecraft\data"

4. 在另外一台電腦將 .minecraft 目錄改名, 執行上面那步的指令.

這樣就可以同步兩邊的存檔和設定了….

家中有小孩都愛玩 minecraft 然後又會用不同電腦或是會常常重灌的很方便.

Ubuntu PPPoE Server 架設

網路上找到的範例都有缺, 主要是缺 pppoe kernel module 的部份, 也不會很難, 在 Ubuntu 18.04 下需要上個 patch 修掉 compile bug.

Read more »

RSS Toeplitz Hash Calculation C Code

Toeplitz RSS(Receive Side Scaling) sample code 如下, 從 ODP Code 借來的

因為是測試用 code, 所以也不要太在乎語法什麼的
輸出可以正確的跑出 microsoft 網站的 sample

$ ./a.out
sip: 187.149.9.66   dip:80.100.142.161 sport:1766   dport:2794   hash: 51ccc178

目前的 code 會計算 4 個 IP
像是這樣

$ ./a.out
sip: 192.168.1.100  dip:10.0.0.100     sport:1000   dport:1000   hash: 8c2cb4f
sip: 193.168.1.100  dip:10.0.0.100     sport:1000   dport:1000   hash: ef1317e8
sip: 194.168.1.100  dip:10.0.0.100     sport:1000   dport:1000   hash: 5f061160
sip: 195.168.1.100  dip:10.0.0.100     sport:1000   dport:1000   hash: 2324d4ee

連檔名都叫 a.out 我真懶

#include <stdint.h>
#include <stdio.h>
#include <endian.h>
#include <string.h>
#include <arpa/inet.h>

/** rss data type */
typedef union {
uint8_t u8[40];
uint32_t u32[10];
} rss_key;

/** IPv4 tuple
*
*/
typedef struct thash_ipv4_tuple {
uint32_t src_addr;
uint32_t dst_addr;
union {
struct {
uint16_t sport;
uint16_t dport;
};
uint32_t sctp_tag;
};
} thash_ipv4_tuple_t;

/** Thash tuple union */
typedef union {
thash_ipv4_tuple_t v4;
//thash_ipv6_tuple_t v6;
} thash_tuple_t;
static const rss_key default_rss = {
.u8 = {
0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa,
}
};

static inline
uint32_t thash_softrss(uint32_t *tuple, uint8_t len,
const rss_key key)
{
uint32_t i, j, ret = 0;

for (j = 0; j < len; j++) {
for (i = 0; i < 32; i++) {
if (tuple[j] & (1 << (31 – i))) {
ret ^= htobe32(((const uint32_t *)
key.u32)[j]) << i | (uint32_t)((uint64_t) (htobe32(((const uint32_t *)key.u32) [j + 1])) >> (32 – i));
}
}
}

return ret;
}
int main(int argc,char *argv[]){
thash_tuple_t tuple;
uint32_t hash;
uint32_t tuple_len;
struct in_addr ip_addr_s,ip_addr_d;
char str_s[15], str_d[15];

#if 0
tuple.v4.src_addr = (uint32_t) inet_addr(“66.9.149.187″);
tuple.v4.dst_addr = (uint32_t) inet_addr(“161.142.100.80″);
ip_addr_s.s_addr = tuple.v4.src_addr;
ip_addr_d.s_addr = tuple.v4.dst_addr;
tuple_len += 2;
tuple.v4.sport = htobe16(2794);
tuple.v4.dport = htobe16(1766);
tuple_len += 1;
#endif

for(int i=0;i<4;i++){
tuple_len = 0;
hash = 0;

tuple.v4.src_addr = (uint32_t) inet_addr(“192.168.1.100″);
tuple.v4.src_addr = be32toh(tuple.v4.src_addr);
tuple.v4.src_addr=tuple.v4.src_addr+i*4;
tuple.v4.src_addr = htobe32(tuple.v4.src_addr);
tuple.v4.dst_addr = (uint32_t) inet_addr(“10.0.0.100″);
ip_addr_s.s_addr = tuple.v4.src_addr;
ip_addr_d.s_addr = tuple.v4.dst_addr;
tuple_len += 2;
tuple.v4.sport = htobe16(1000);
tuple.v4.dport = htobe16(1000);
tuple_len += 1;

if (tuple_len){
tuple.v4.src_addr = be32toh(tuple.v4.src_addr);
tuple.v4.dst_addr = be32toh(tuple.v4.dst_addr);
tuple.v4.sctp_tag = be32toh(tuple.v4.sctp_tag);
hash = thash_softrss((uint32_t *)&tuple,
tuple_len, default_rss);
}

ip_addr_s.s_addr = htobe32(tuple.v4.src_addr);
ip_addr_d.s_addr = htobe32(tuple.v4.dst_addr);
strcpy(str_s,inet_ntoa(ip_addr_s));
strcpy(str_d,inet_ntoa(ip_addr_d));
printf(“sip: %-14s dip:%-14s sport:%-6d dport:%-6d hash: %x \n",
str_s,str_d,
tuple.v4.sport,
tuple.v4.dport, hash);

}

return hash;
}

附帶一提, 如果在 Linux 下要修改 hash key . 可以用 ethtool 這個指令, ex:

$ ethtool -X enp5s0f4 hkey 6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a:6d:5a

ref.
Verifying the RSS Hash Calculation : 可以比對計算出是不是正確
Symmetric RSS : 有趣的文章, 提到原來的功能沒有辦法有效的 hash , 將所有的 key 都改 0x6d5a 就可以
Scalable TCP Session Monitoring with Symmetric Receive-side Scaling
Scaling in the Linux Networking Stack
odp_classification.c

Ubuntu Build Original Linux Kernel

最好的方式應該是這一篇文章

不要再用什麼 fakeroot 去編了, 失敗率超高, 尤其是在 ARM 平台

https://wiki.ubuntu.com/KernelTeam/GitKernelBuild
Read more »

Debian 使用 backports 和 experimental 的方法

Debian stable 的套件都很舊, 有時候要找新一點的 binary 時, 就需要用到 backports 或是 experimental
Read more »

QEMU change default nat address configure file

In ubuntu, if install libvirt, it will bring up bridge interface virbr0 and configure the ip address 192.168.122.1

modify /etc/libvirt/qemu/networks/default.xml can change that

小米手環2無法充電的問題

看到很多人在討論小米手環2 無法充電的問題

很多人說故障率很高, 但是有些人又沒有碰過

我有一條一代一下就不能充電了, 二代也是一樣, 之前也是不能充電, 不知道怎麼樣弄了一下就可以充了.

過了大概一個多月, 這幾天沒電了要拿去充, 又不能充了, 換很多個 USB 都沒有用.

今天仔細看了一下, 感覺充電接頭的地方有氧化現像, 拿了螺絲起子硬刮了一下充電接頭的地方……

果然又頭好壯壯了.