Sometimes I want to see processes outside the default routing table with `-T -0', sometimes those in in a specific one with `-T 3' (for testing).
Since others have poked around with routing tables and/or domains as of late, perhaps this deemed useful enough? Semantically, filtering is identical to that of users: pick or hide one; this makes the code pretty much copy/paste within top(1), manual wording and command line flag is taken from pgrep(1). pgrep is currently the only way to identify processes by routing table. After netstat(1)'s relatively recent addition of `-R', filtering in top makes for a quite handy set of tooling around rtable(4). Feedback? OK? Index: display.c =================================================================== RCS file: /cvs/src/usr.bin/top/display.c,v retrieving revision 1.63 diff -u -p -r1.63 display.c --- display.c 26 Jul 2020 21:59:16 -0000 1.63 +++ display.c 9 Aug 2020 17:55:56 -0000 @@ -824,6 +824,8 @@ show_help(void) "r count pid - renice process `pid' to nice value `count'\n" "S - toggle the display of system processes\n" "s time - change delay between displays to `time' seconds\n" + "T [-]rtable - show processes associated with routing table `rtable'\n" + " (T+ shows all, T -rtable hides rtable)\n" "u [-]user - show processes for `user' (u+ shows all, u -user hides user)\n" "\n"); Index: machine.c =================================================================== RCS file: /cvs/src/usr.bin/top/machine.c,v retrieving revision 1.107 diff -u -p -r1.107 machine.c --- machine.c 6 Jul 2020 16:27:59 -0000 1.107 +++ machine.c 9 Aug 2020 18:06:36 -0000 @@ -414,7 +414,7 @@ get_process_info(struct system_info *si, int (*compare) (const void *, const void *)) { int show_idle, show_system, show_threads, show_uid, show_pid, show_cmd; - int hide_uid; + int show_rtable, hide_rtable, hide_uid; int total_procs, active_procs; struct kinfo_proc **prefp, *pp; int what = KERN_PROC_ALL; @@ -446,6 +446,8 @@ get_process_info(struct system_info *si, show_uid = sel->uid != (uid_t)-1; hide_uid = sel->huid != (uid_t)-1; show_pid = sel->pid != (pid_t)-1; + show_rtable = sel->rtableid != -1; + hide_rtable = sel->hrtableid != -1; show_cmd = sel->command != NULL; /* count up process states and get pointers to interesting procs */ @@ -474,6 +476,8 @@ get_process_info(struct system_info *si, (!hide_uid || pp->p_ruid != sel->huid) && (!show_uid || pp->p_ruid == sel->uid) && (!show_pid || pp->p_pid == sel->pid) && + (!hide_rtable || pp->p_rtableid != sel->hrtableid) && + (!show_rtable || pp->p_rtableid == sel->rtableid) && (!show_cmd || cmd_matches(pp, sel->command))) { *prefp++ = pp; active_procs++; Index: machine.h =================================================================== RCS file: /cvs/src/usr.bin/top/machine.h,v retrieving revision 1.29 diff -u -p -r1.29 machine.h --- machine.h 25 Jun 2020 20:38:41 -0000 1.29 +++ machine.h 9 Aug 2020 17:50:14 -0000 @@ -77,6 +77,8 @@ struct process_select { uid_t uid; /* only this uid (unless uid == -1) */ uid_t huid; /* hide this uid (unless huid == -1) */ pid_t pid; /* only this pid (unless pid == -1) */ + int rtableid; /* only this rtable (unless rtableid == -1) */ + int hrtableid; /* hide this rtable (unless hrtableid == -1) */ char *command;/* only this command (unless == NULL) */ }; Index: top.1 =================================================================== RCS file: /cvs/src/usr.bin/top/top.1,v retrieving revision 1.75 diff -u -p -r1.75 top.1 --- top.1 26 Jul 2020 21:59:16 -0000 1.75 +++ top.1 9 Aug 2020 18:16:12 -0000 @@ -38,6 +38,7 @@ .Op Fl o Oo - Oc Ns Ar field .Op Fl p Ar pid .Op Fl s Ar time +.Op Fl T Oo - Oc Ns Ar rtable .Op Fl U Oo - Oc Ns Ar user .Op Ar number .Ek @@ -179,6 +180,14 @@ Set the delay between screen updates to seconds. The value may be fractional, to permit delays of less than 1 second. The default delay between updates is 5 seconds. +.It Fl T Oo - Oc Ns Ar rtable +Display only processes associated with the specified routing table +.Ar rtable . +.Sq T+ +shows processes associated with all routing tables. +The +.Sq - +prefix hides proccesses associated with a single routing table. .It Fl U Oo - Oc Ns Ar user Show only those processes owned by username or UID .Ar user . @@ -371,6 +380,14 @@ Toggle the display of system processes. Set the delay between screen updates to .Ar time seconds. +.It T Oo - Oc Ns Ar rtable +Display only processes associated with the specified routing table +.Ar rtable . +.Sq T+ +shows processes associated with all routing tables. +The +.Sq - +prefix hides proccesses associated with a single routing table. .It u Oo - Oc Ns Ar user Show only those processes owned by username or UID .Ar user . Index: top.c =================================================================== RCS file: /cvs/src/usr.bin/top/top.c,v retrieving revision 1.104 diff -u -p -r1.104 top.c --- top.c 26 Jul 2020 21:59:16 -0000 1.104 +++ top.c 9 Aug 2020 18:06:43 -0000 @@ -29,6 +29,7 @@ */ #include <sys/types.h> +#include <sys/socket.h> #include <curses.h> #include <err.h> #include <errno.h> @@ -132,6 +133,7 @@ struct statics statics; #define CMD_pagedown 26 #define CMD_pageup 27 #define CMD_grep2 28 +#define CMD_rtable 29 static void usage(void) @@ -140,7 +142,7 @@ usage(void) fprintf(stderr, "usage: %s [-1bCHIinqSu] [-d count] [-g string] [-o [-]field] " - "[-p pid] [-s time]\n\t[-U [-]user] [number]\n", + "[-p pid] [-s time]\n\t[-T [-]rtable] [-U [-]user] [number]\n", __progname); } @@ -207,13 +209,39 @@ filterpid(char buf[], int hl) return 0; } +static int +filterrtable(char buf[]) +{ + const char *errstr; + char *bufp = buf; + uint32_t *rtableidp; + uint32_t rtableid; + + if (bufp[0] == '-') { + bufp++; + rtableidp = &ps.hrtableid; + ps.rtableid = -1; + } else { + rtableidp = &ps.rtableid; + ps.hrtableid = -1; + } + + rtableid = strtonum(bufp, 0, RT_TABLEID_MAX, &errstr); + if (errstr == NULL) { + *rtableidp = rtableid; + return 0; + } + + return -1; +} + static void parseargs(int ac, char **av) { char *endp; int i; - while ((i = getopt(ac, av, "1SHICbinqus:d:p:U:o:g:")) != -1) { + while ((i = getopt(ac, av, "1SHICbinqus:d:p:U:o:g:T:")) != -1) { switch (i) { case '1': combine_cpus = 1; @@ -305,6 +333,12 @@ parseargs(int ac, char **av) err(1, NULL); break; + case 'T': + if (filterrtable(optarg) == -1) + new_message(MT_delayed, + "%s: invalid routing table", optarg); + break; + default: usage(); exit(1); @@ -357,6 +391,8 @@ main(int argc, char *argv[]) ps.uid = (uid_t)-1; ps.huid = (uid_t)-1; ps.pid = (pid_t)-1; + ps.rtableid = -1; + ps.hrtableid = -1; ps.command = NULL; /* get preset options from the environment */ @@ -632,7 +668,7 @@ rundisplay(void) char ch, *iptr; int change, i; struct pollfd pfd[1]; - static char command_chars[] = "\f qh?en#sdkriIuSopCHg+P109)(/"; + static char command_chars[] = "\f qh?en#sdkriIuSopCHg+P109)(/T"; /* * assume valid command unless told @@ -973,6 +1009,8 @@ rundisplay(void) ps.uid = (uid_t)-1; /* uid */ ps.huid = (uid_t)-1; ps.pid = (pid_t)-1; /* pid */ + ps.rtableid = -1; /* rtableid */ + ps.hrtableid = -1; ps.system = old_system; ps.command = NULL; /* grep */ hlpid = (pid_t)-1; @@ -996,6 +1034,24 @@ rundisplay(void) skip -= max_topn / 2; if (skip < 0) skip = 0; + break; + case CMD_rtable: + new_message(MT_standout, + "Routing table: "); + if (readline(tempbuf, sizeof(tempbuf)) > 0) { + if (tempbuf[0] == '+' && tempbuf[1] == '\0') { + ps.rtableid = -1; + ps.hrtableid = -1; + } else if (filterrtable(tempbuf) == -1) { + new_message(MT_standout, + " %s: invalid routing table", + tempbuf[0] == '-' ? tempbuf + 1 : + tempbuf); + no_command = true; + } + putr(); + } else + clear_message(); break; default: new_message(MT_standout, " BAD CASE IN SWITCH!");