On 2009/07/22 15:29, Claudio Jeker wrote:
> 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
I like adding the route information here, but I also like having as much
operational information as possible directly in sh nex and sh sum. There's
a little slack space in Nexthop/Route/Gateway, if we remove that we would
have space for an indication after the iface. Not sure if it's too messy
though.
Nexthop State Route Prio Gateway Iface
85.158.44.145 valid 85.158.44.144/28 4 connected re0 (1000M)
Index: bgpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.144
diff -u -p -r1.144 bgpctl.c
--- bgpctl.c 21 Jul 2009 11:49:36 -0000 1.144
+++ bgpctl.c 22 Jul 2009 14:42:43 -0000
@@ -65,7 +65,7 @@ void show_interface_head(void);
int ift2ifm(int);
const char * get_media_descr(int);
const char * get_linkstate(int, int);
-void print_baudrate(u_int64_t);
+void print_baudrate(u_int64_t, int);
int show_interface_msg(struct imsg *);
void show_rib_summary_head(void);
void print_prefix(struct bgpd_addr *, u_int8_t, u_int8_t);
@@ -848,35 +848,65 @@ show_fib_msg(struct imsg *imsg)
void
show_nexthop_head(void)
{
- printf("%-20s %-10s\n", "Nexthop", "State");
+ printf("%-15s %-7s %-20s%-4s %-15s %-14s\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("%-15s %-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 %-15s ", 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 %-15s ", k6->priority,
+ k6->flags & F_CONNECTED ? "connected" :
+ log_in6addr(&k6->nexthop));
+ break;
+ default:
+ printf("unknown address family %d\n", p->addr.af);
+ return (0);
+ }
if (p->kif.ifname[0]) {
- printf("%-8s", p->kif.ifname);
+ 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);
- }
- }
+ if ((ift2ifm(p->kif.media_type) != 0) &&
+ p->kif.baudrate)
+ print_baudrate(p->kif.baudrate, 0);
+ else
+ printf("up");
+ } else
+ printf("down");
+ printf(")");
}
printf("\n");
break;
@@ -956,16 +986,16 @@ get_linkstate(int media_type, int link_s
}
void
-print_baudrate(u_int64_t baudrate)
+print_baudrate(u_int64_t baudrate, int verb)
{
if (baudrate > IF_Gbps(1))
- printf("%llu GBit/s", baudrate / IF_Gbps(1));
+ printf("%llu%s", baudrate / IF_Gbps(1), verb ? " GBit/s" : "G");
else if (baudrate > IF_Mbps(1))
- printf("%llu MBit/s", baudrate / IF_Mbps(1));
+ printf("%llu%s", baudrate / IF_Mbps(1), verb ? " MBit/s" : "M");
else if (baudrate > IF_Kbps(1))
- printf("%llu KBit/s", baudrate / IF_Kbps(1));
+ printf("%llu%s", baudrate / IF_Kbps(1), verb ? " KBit/s" : "K");
else
- printf("%llu Bit/s", baudrate);
+ printf("%llu%s", baudrate, verb ? " Bit/s" : "b");
}
int
@@ -991,7 +1021,7 @@ show_interface_msg(struct imsg *imsg)
if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) {
printf(", ");
- print_baudrate(k->baudrate);
+ print_baudrate(k->baudrate, 1);
}
printf("\n");
break;