So here is another try and I guess some people will not like it.
BGP unlike other routing protocols needs to find the true nexthop because
the passed IP in the NEXT_HOP attribute can be more then one hop away.
So bgpd uses the fib (as stored in the parent) to figure out the gateway
for a nexthop. In the beginning we had some troubles with correctly
tracking those nexthops (I think all problems are fixed now but that does
not matter). bgpctl show nexthop should return all necessary information
to understand the decision bgpd did. The current output is missing the
single most important information -- the route that is used to verify this
nexthop. Without this info nobody knows why a wrong nexthop is used.

This diff sends the kroute to bgpctl so that we can show the route which
got used.

Nexthop          State   Route               Prio Gateway          Iface   
62.48.4.1        valid   62.48.4.0/24           4 connected        fxp0    
62.48.0.1        invalid 

Having the link state in the output would be nice but there are only about
4-5 char left till we hit the 80-char wide wall. I tried out to use a "*"
for valid nexthops but that single char (even though the most important
one) is easily missed in longer outputs.

I'm open to suggestions
-- 
:wq Claudio

Index: bgpctl/bgpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.144
diff -u -p -r1.144 bgpctl.c
--- bgpctl/bgpctl.c     21 Jul 2009 11:49:36 -0000      1.144
+++ bgpctl/bgpctl.c     22 Jul 2009 13:20:33 -0000
@@ -848,35 +848,56 @@ show_fib_msg(struct imsg *imsg)
 void
 show_nexthop_head(void)
 {
-       printf("%-20s %-10s\n", "Nexthop", "State");
+       printf("%-16s %-7s %-20s%-4s %-16s %-8s\n", "Nexthop", "State",
+           "Route", "Prio", "Gateway", "Iface");
 }
 
 int
 show_nexthop_msg(struct imsg *imsg)
 {
        struct ctl_show_nexthop *p;
-       int                      ifms_type;
+       struct kroute           *k;
+       struct kroute6          *k6;
+       char                    *s;
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_NEXTHOP:
                p = imsg->data;
-               printf("%-20s %-10s", log_addr(&p->addr),
+               printf("%-16s %-7s ", log_addr(&p->addr),
                    p->valid ? "valid" : "invalid");
+               if (!p->krvalid) {
+                       printf("\n");
+                       return (0);
+               }
+               switch (p->addr.af) {
+               case AF_INET:
+                       k = &p->kr.kr4;
+                       if (asprintf(&s, "%s/%u", inet_ntoa(k->prefix),
+                           k->prefixlen) == -1)
+                               err(1, NULL);
+                       printf("%-20s", s);
+                       free(s);
+                       printf("%4i %-16s ", k->priority,
+                           k->flags & F_CONNECTED ? "connected" :
+                           inet_ntoa(k->nexthop));
+                       break;
+               case AF_INET6:
+                       k6 = &p->kr.kr6;
+                       if (asprintf(&s, "%s/%u", log_in6addr(&k6->prefix),
+                           k6->prefixlen) == -1)
+                               err(1, NULL);
+                       printf("%-20s", s);
+                       free(s);
+                       printf("%4i %-16s ", k6->priority,
+                           k6->flags & F_CONNECTED ? "connected" :
+                           log_in6addr(&k6->nexthop));
+                       break;
+               default:
+                       printf("unknown address familiy %d\n", p->addr.af);
+                       return (0);
+               }
                if (p->kif.ifname[0]) {
                        printf("%-8s", p->kif.ifname);
-                       if (p->kif.flags & IFF_UP) {
-                               printf("UP");
-                               ifms_type = ift2ifm(p->kif.media_type);
-                               if (ifms_type != 0)
-                                       printf(", %s, %s",
-                                           get_media_descr(ifms_type),
-                                           get_linkstate(ifms_type,
-                                           p->kif.link_state));
-                               if (p->kif.baudrate) {
-                                       printf(", ");
-                                       print_baudrate(p->kif.baudrate);
-                               }
-                       }
                }
                printf("\n");
                break;
Index: bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.242
diff -u -p -r1.242 bgpd.h
--- bgpd/bgpd.h 20 Jul 2009 15:03:16 -0000      1.242
+++ bgpd/bgpd.h 22 Jul 2009 11:48:34 -0000
@@ -437,10 +437,13 @@ struct pftable_msg {
 
 struct ctl_show_nexthop {
        struct bgpd_addr        addr;
-       struct bgpd_addr        gateway;
        struct kif              kif;
+       union {
+               struct kroute           kr4;
+               struct kroute6          kr6;
+       } kr;
        u_int8_t                valid;
-       u_int8_t                connected;
+       u_int8_t                krvalid;;
 };
 
 struct ctl_neighbor {
Index: bgpd/kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.170
diff -u -p -r1.170 kroute.c
--- bgpd/kroute.c       20 Jul 2009 15:03:16 -0000      1.170
+++ bgpd/kroute.c       22 Jul 2009 11:46:53 -0000
@@ -587,26 +587,17 @@ kr_show_route(struct imsg *imsg)
                                case AF_INET:
                                        kr = h->kroute;
                                        snh.valid = kroute_validate(&kr->r);
-                                       snh.connected =
-                                           kr->r.flags & F_CONNECTED;
-                                       if ((snh.gateway.v4.s_addr =
-                                           kr->r.nexthop.s_addr) != 0)
-                                               snh.gateway.af = AF_INET;
+                                       snh.krvalid = 1;
+                                       memcpy(&snh.kr.kr4, &kr->r,
+                                           sizeof(snh.kr.kr4));
                                        ifindex = kr->r.ifindex;
                                        break;
                                case AF_INET6:
                                        kr6 = h->kroute;
                                        snh.valid = kroute6_validate(&kr6->r);
-                                       snh.connected =
-                                           kr6->r.flags & F_CONNECTED;
-                                       if (memcmp(&kr6->r.nexthop,
-                                           &in6addr_any,
-                                           sizeof(struct in6_addr)) != 0) {
-                                               snh.gateway.af = AF_INET6;
-                                               memcpy(&snh.gateway.v6,
-                                                   &kr6->r.nexthop,
-                                                   sizeof(struct in6_addr));
-                                       }
+                                       snh.krvalid = 1;
+                                       memcpy(&snh.kr.kr6, &kr6->r,
+                                           sizeof(snh.kr.kr6));
                                        ifindex = kr6->r.ifindex;
                                        break;
                                }

Reply via email to