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!");

Reply via email to