1# Introduction 2 3Compile ff tools 4 5 make 6 7Install ff tools, all ff tools will be installed to `/usr/local/bin/f-stack/`, and some soft link will be created in `/usr/local/bin`, such as `ff_top`,`ff_traffic`, etc. 8 9 make install 10 11Directory `compat` implements an ipc library using dpdk `rte_ring` and ports some source files compatible with FreeBSD and Linux. 12 13Directory `sbin` contains all the tools binary that compiled. 14 15All other directories are useful tools ported from FreeBSD. 16Since F-Stack is multi-process architecture and every process has an independent stack, so we must communicate with every F-Stack process. 17Each tool add an option `-p`(Which F-Stack process to communicate with, default 0), except that, it is same with the original FreeBSD. 18 19Note that these tools must be executed serially. 20 21# sysctl 22Usage: 23``` 24sysctl -p <f-stack proc_id> [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ... 25sysctl -p <f-stack proc_id> [-bdehNnoqTtWx] [ -B <bufsize> ] -a 26``` 27For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?sysctl). 28 29# ifconfig 30Usage: 31``` 32ifconfig -p <f-stack proc_id> [-f type:format] %sinterface address_family 33 [address [dest_address]] [parameters] 34 ifconfig -p <f-stack proc_id> interface create 35 ifconfig -p <f-stack proc_id> -a %s[-d] [-m] [-u] [-v] [address_family] 36 ifconfig -p <f-stack proc_id> -l [-d] [-u] [address_family] 37 ifconfig -p <f-stack proc_id> %s[-d] [-m] [-u] [-v] 38``` 39Unsupported interfaces or parameters: 40``` 41inet6 42MAC(Mandatory Access Control) 43media 44SFP/SFP+ 45IEEE80211 Wireless 46pfsync 47LAGG LACP 48jail 49``` 50For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?ifconfig). 51 52# route 53Usage: 54``` 55route -p <f-stack proc_id> [-46dnqtv] command [[modifiers] args] 56``` 57Examples: 58``` 59 Add a default route: 60 61 ./sbin/route -p 0 add -net 0.0.0.0/0 192.168.1.1 62 63 A shorter version of adding a default route can also be written as: 64 65 ./sbin/route -p 0 add default 192.168.1.1 66 67 Add a static route to the 172.16.10.0/24 network via the 172.16.1.1 gate- 68 way: 69 70 ./sbin/route -p 0 add -net 172.16.10.0/24 172.16.1.1 71 72 Change the gateway of an already established static route in the routing 73 table: 74 75 ./sbin/route -p 0 change -net 172.16.10.0/24 172.16.1.2 76 77 Display the route for a destination network: 78 79 ./sbin/route -p 0 show 172.16.10.0 80 81 Delete a static route from the routing table: 82 83 ./sbin/route -p 0 delete -net 172.16.10.0/24 172.16.1.2 84 85 Remove all routes from the routing table: 86 87 ./sbin/route -p 0 flush 88 89 FreeBSD uses `netstat -rn ` to list the route table which we havn't ported, 90 you can execute the following command instead, `-d` means debug mode, `-v` 91 means verbose. 92 ./sbin/route -p 0 -d -v flush 93``` 94Note that, if you want to modify the route table, you must use `-p` to execute the same command for each f-stack process. 95 96For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?route). 97 98# top 99Usage: 100``` 101top [-p <f-stack proc_id>] [-d <secs>] [-n num] 102``` 103Examples: 104``` 105./sbin/top 106 107|---------|---------|---------|---------------| 108| idle| sys| usr| loop| 109|---------|---------|---------|---------------| 110| 99.69%| 0.00%| 0.31%| 8214640| 111| 99.77%| 0.00%| 0.23%| 8205713| 112| 5.02%| 45.19%| 49.79%| 769435| 113| 0.00%| 19.88%| 80.12%| 393| 114| 0.00%| 20.28%| 79.72%| 395| 115| 0.00%| 15.50%| 84.50%| 403| 116| 0.00%| 31.31%| 68.69%| 427| 117| 32.07%| 8.78%| 59.15%| 2342862| 118| 99.79%| 0.00%| 0.21%| 9974439| 119| 99.81%| 0.00%| 0.19%| 7336153| 120| 99.79%| 0.00%| 0.21%| 8147676| 121``` 122 123# netstat 124Usage: 125``` 126 netstat -P <f-stack proc_id> [-46AaLnRSTWx] [-f protocol_family | -p protocol] 127 netstat -P <f-stack proc_id> -i | -I interface [-46abdhnW] [-f address_family] 128 netstat -P <f-stack proc_id> -w wait [-I interface] [-46d] [-q howmany] 129 netstat -P <f-stack proc_id> -s [-46sz] [-f protocol_family | -p protocol] 130 netstat -P <f-stack proc_id> -i | -I interface -s [-46s] 131 [-f protocol_family | -p protocol] 132 netstat -P <f-stack proc_id> -B [-z] [-I interface] 133 netstat -P <f-stack proc_id> -r [-46AnW] [-F fibnum] [-f address_family] 134 netstat -P <f-stack proc_id> -rs [-s] 135 netstat -P <f-stack proc_id> -g [-46W] [-f address_family] 136 netstat -P <f-stack proc_id> -gs [-46s] [-f address_family] 137 netstat -P <f-stack proc_id> -Q 138``` 139 140Unsupported commands or features: 141``` 142-M 143-N 144-m 145ipv6 146netgraph 147ipsec 148``` 149 150For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?netstat). 151 152# ngctl 153Usage: 154``` 155ngctl -p <f-stack proc_id> [-d] [-f file] [-n name] [command ...] 156``` 157 158About interactive mode: 159- if you have `libedit` in your system, you can turn on `MK_HAVE_LIBEDIT` in `opts.mk`, 160 the interactive mode will support generic line editing, history functions. 161 162 163For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?ngctl). 164 165# ipfw 166Usage: 167``` 168ipfw -P <f-stack proc_id> [-abcdefhnNqStTv] <command> 169 170where <command> is one of the following: 171 172add [num] [set N] [prob x] RULE-BODY 173{pipe|queue} N config PIPE-BODY 174[pipe|queue] {zero|delete|show} [N{,N}] 175nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|reset| 176 reverse|proxy_only|redirect_addr linkspec| 177 redirect_port linkspec|redirect_proto linkspec} 178set [disable N... enable N...] | move [rule] X to Y | swap X Y | show 179set N {show|list|zero|resetlog|delete} [N{,N}] | flush 180table N {add ip[/bits] [value] | delete ip[/bits] | flush | list} 181table all {flush | list} 182 183RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST] 184ACTION: check-state | allow | count | deny | unreach{,6} CODE | 185 skipto N | {divert|tee} PORT | forward ADDR | 186 pipe N | queue N | nat N | setfib FIB | reass 187PARAMS: [log [logamount LOGLIMIT]] [altq QUEUE_NAME] 188ADDR: [ MAC dst src ether_type ] 189 [ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ] 190 [ ipv6|ip6 from IP6ADDR [ PORT ] to IP6ADDR [ PORTLIST ] ] 191IPADDR: [not] { any | me | ip/bits{x,y,z} | table(t[,v]) | IPLIST } 192IP6ADDR: [not] { any | me | me6 | ip6/bits | IP6LIST } 193IP6LIST: { ip6 | ip6/bits }[,IP6LIST] 194IPLIST: { ip | ip/bits | ip:mask }[,IPLIST] 195OPTION_LIST: OPTION [OPTION_LIST] 196OPTION: bridged | diverted | diverted-loopback | diverted-output | 197 {dst-ip|src-ip} IPADDR | {dst-ip6|src-ip6|dst-ipv6|src-ipv6} IP6ADDR | 198 {dst-port|src-port} LIST | 199 estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST | 200 iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC | 201 ipttl LIST | ipversion VER | keep-state | layer2 | limit ... | 202 icmp6types LIST | ext6hdr LIST | flow-id N[,N] | fib FIB | 203 mac ... | mac-type LIST | proto LIST | {recv|xmit|via} {IF|IPADDR} | 204 setup | {tcpack|tcpseq|tcpwin} NN | tcpflags SPEC | tcpoptions SPEC | 205 tcpdatalen LIST | verrevpath | versrcreach | antispoof 206``` 207Note [dummynet](https://www.freebsd.org/cgi/man.cgi?query=dummynet) is not supported yet. 208 209For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?ipfw) or [handbook](https://www.freebsd.org/doc/handbook/firewalls-ipfw.html). 210 211# arp 212Usage 213``` 214usage: arp -p <f-stack proc_id> [-n] [-i interface] hostname 215 arp -p <f-stack proc_id> [-n] [-i interface] -a 216 arp -p <f-stack proc_id> -d hostname [pub] 217 arp -p <f-stack proc_id> -d [-i interface] -a 218 arp -p <f-stack proc_id> -s hostname ether_addr [temp] [reject | blackhole] [pub [only]] 219 arp -p <f-stack proc_id> -S hostname ether_addr [temp] [reject | blackhole] [pub [only]] 220 arp -p <f-stack proc_id> -f filename 221``` 222 223For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?arp). 224 225# traffic 226Usage: 227``` 228traffic [-p <f-stack proc_id>] [-d <secs>] [-n num] 229``` 230Examples: 231``` 232./sbin/traffic 233 234|--------------------|--------------------|--------------------|--------------------| 235| rx packets| rx bytes| tx packets| tx bytes| 236|--------------------|--------------------|--------------------|--------------------| 237| 0| 0| 0| 0| 238| 298017| 30590860| 590912| 230712836| 239| 475808| 49008224| 951616| 372081856| 240| 474720| 48896160| 949440| 371231040| 241| 475296| 48955488| 950592| 371681472| 242| 475040| 48929120| 950080| 371481280| 243| 474368| 48859904| 948736| 370955776| 244| 475616| 48988448| 951232| 371931712| 245| 475552| 48981856| 951104| 371881664| 246| 476128| 49041184| 952256| 372332096| 247| 475680| 48995040| 951360| 371981760| 248| 475552| 48981856| 951104| 371881664| 249| 475488| 48975264| 950976| 371831616| 250| 473440| 48764320| 946880| 370230080| 251``` 252 253# how to implement a custom tool for communicating with F-Stack process 254 255Add a new FF_MSG_TYPE in ff_msg.h: 256``` 257enum FF_MSG_TYPE { 258 FF_UNKNOWN = 0, 259 FF_SYSCTL, 260 FF_HELLOWORLD, 261}; 262``` 263 264Define a structure used to communicate: 265``` 266struct ff_helloworld_args { 267 void *request; 268 size_t req_len; 269 void *reply; 270 size_t rep_len; 271}; 272``` 273Note that, when using struct ff_helloworld_args, pointers in this structure must point to the addresses range from ff_msg.buf_addr and ff_msg.buf_addr+ff_msg.buf_len, ff_msg.buf_len is (10240 - sizeof(struct ff_msg)). 274 275And add it to ff_msg: 276``` 277struct ff_msg { 278 ... 279 union { 280 struct ff_sysctl_args sysctl; 281 struct ff_helloworld_args helloworld; 282 }; 283}; 284``` 285 286Modify ff_dpdk_if.c, add a handle function: 287``` 288static inline void 289handle_helloworld_msg(struct ff_msg *msg, uint16_t proc_id) 290{ 291 printf("helloworld msg recved.\n"); 292 msg->result = 0; 293 rte_ring_enqueue(msg_ring[proc_id].ring[1], msg); 294} 295 296static inline void 297handle_msg(struct ff_msg *msg, uint16_t proc_id) 298{ 299 switch (msg->msg_type) { 300 case FF_SYSCTL: 301 handle_sysctl_msg(msg, proc_id); 302 break; 303 case FF_HELLOWORLD: 304 handle_helloworld_msg(msg, proc_id); 305 default: 306 handle_default_msg(msg, proc_id); 307 break; 308 } 309} 310``` 311 312Create helloworld.c: 313 314``` 315int main() 316{ 317 struct ff_msg *msg = ff_ipc_msg_alloc(); 318 319 char *buf = msg->buf_addr; 320 321 msg->helloworld.request = buf; 322 memcpy(msg->helloworld.request, "hello", 5); 323 msg->helloworld.req_len = 5; 324 buf += 5; 325 326 msg->helloworld.reply = buf; 327 msg->helloworld.rep_len = 10; 328 329 ff_ipc_send(msg, 0); 330 331 struct ff_msg *retmsg; 332 ff_ipc_recv(retmsg, 0); 333 assert(remsg==msg); 334 335 ff_ipc_msg_free(msg); 336} 337 338``` 339 340The Makefile may like this: 341``` 342TOPDIR?=${CURDIR}/../.. 343 344PROG=helloworld 345 346include ${TOPDIR}/tools/prog.mk 347``` 348