diff -u --recursive nest/config.Y.orig bird-1.3.6/nest/config.Y
--- nest/config.Y.orig	2012-01-10 14:42:47.000000000 +0200
+++ nest/config.Y	2012-02-10 15:39:20.000000000 +0200
@@ -338,10 +338,13 @@
 { cmd_show_memory(); } ;
 
 CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
-{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
+{ proto_apply_show_cmd($3, proto_cmd_show, 0, NULL); } ;
 
 CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
-{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
+{ proto_apply_show_cmd($4, proto_cmd_show, 1, NULL); } ;
+
+CF_CLI(SHOW PROTOCOLS BGP, proto_patt2, [<protocol> | \"<pattern>\"], [[Show BGP routing protocol short summary]])
+{ proto_apply_show_cmd($4, proto_cmd_show, 0, "BGP"); } ;
 
 optsym:
    SYM
diff -u --recursive nest/proto.c.orig nest/proto.c
--- nest/proto.c.orig	2012-01-10 14:42:47.000000000 +0200
+++ nest/proto.c	2012-02-10 16:57:21.000000000 +0200
@@ -917,25 +917,39 @@
 #endif
 
 void
-proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
+proto_cmd_show(struct proto *p, unsigned int verbose, int cnt, char *n)
 {
   byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
+  char proto_status[256], route_status[20];
+  struct proto_stats *s;
 
-  /* First protocol - show header */
+  /* Display protocol table - show header */
   if (!cnt)
-    cli_msg(-2002, "name     proto    table    state  since       info");
+    /* Columns depend on value of n. If n is NULL then show all protocols */
+    if (n == NULL) {
+      cli_msg(-2002, "name     proto    table    state  since       info");
+    } else 
+    if (p->proto->show_summary_title) 
+      p->proto->show_summary_title();
 
-  buf[0] = 0;
-  if (p->proto->get_status)
-    p->proto->get_status(p, buf);
   tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change);
-  cli_msg(-1002, "%-8s %-8s %-8s %-5s  %-10s  %s",
-	  p->name,
-	  p->proto->name,
-	  p->table->name,
-	  proto_state_name(p),
-	  tbuf,
-	  buf);
+  buf[0] = 0;
+
+  if ( n == NULL ) {
+    if (p->proto->get_status)
+      p->proto->get_status(p, buf);
+    cli_msg(-1002, "%-8s %-8s %-8s %-5s  %-10s  %s",
+		p->name,
+		p->proto->name,
+		p->table->name,
+		proto_state_name(p),
+		tbuf,
+		buf);
+
+  } else 
+  if (p->proto->show_proto_summary)
+    p->proto->show_proto_summary(p);
+
   if (verbose)
     {
       if (p->cf->dsc)
@@ -1066,6 +1080,28 @@
 }
 
 static void
+proto_apply_show_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, unsigned int, int, char *), unsigned int verbose, char *n)
+{
+  struct proto *p;
+  if (s->class != SYM_PROTO)
+    {
+      cli_msg(9002, "%s is not a protocol", s->name);
+      return;
+    }
+
+  p = ((struct proto_config *)s->def)->proto;
+  /* If n is present then check protocol type */
+  if ( n != NULL && 
+	strcmp(p->proto->name, n) )
+  {
+	cli_msg(9002, "%s is not a %s protocol", s->name, n);
+  }
+
+  cmd(p, verbose, 0, n);
+  cli_msg(0, "");
+}
+
+static void
 proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, unsigned int, int), unsigned int arg)
 {
   int cnt = 0;
@@ -1085,6 +1121,26 @@
     cli_msg(0, "");
 }
 
+static void
+proto_apply_show_cmd_patt(char *patt, void (* cmd)(struct proto *, unsigned int, int, char *), unsigned int verbose, char *n)
+{
+  int cnt = 0;
+
+  node *nn;
+  WALK_LIST(nn, proto_list)
+    {
+      struct proto *p = SKIP_BACK(struct proto, glob_node, nn);
+      if ( (!patt || patmatch(patt, p->name)) &&
+        (n == NULL || patmatch(n, p->proto->name)) )
+           cmd(p, verbose, cnt++, n);
+    }
+
+  if (!cnt)
+    cli_msg(8003, "No protocols match");
+  else
+    cli_msg(0, "");
+}
+
 void
 proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, unsigned int, int),
 		int restricted, unsigned int arg)
@@ -1098,6 +1154,16 @@
     proto_apply_cmd_symbol(ps.ptr, cmd, arg);
 }
 
+void
+proto_apply_show_cmd(struct proto_spec ps, void (* cmd)(struct proto *, unsigned int, int, char *),
+                unsigned int verbose, char *n)
+{
+  if (ps.patt)
+    proto_apply_show_cmd_patt(ps.ptr, cmd, verbose, n);
+  else
+    proto_apply_show_cmd_symbol(ps.ptr, cmd, verbose, n);
+}
+
 struct proto *
 proto_get_named(struct symbol *sym, struct protocol *pr)
 {
diff -u --recursive nest/protocol.h.orig bird-1.3.6/nest/protocol.h
--- nest/protocol.h.orig	2012-01-10 14:42:47.000000000 +0200
+++ nest/protocol.h	2012-02-10 15:35:16.000000000 +0200
@@ -53,6 +53,8 @@
   void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
   int (*get_attr)(struct eattr *, byte *buf, int buflen);	/* ASCIIfy dynamic attribute (returns GA_*) */
   void (*show_proto_info)(struct proto *);	/* Show protocol info (for `show protocols all' command) */
+  void (*show_proto_summary)(struct proto *);	/* Show protocol summary (for `show protocols bgp` command */
+  void (*show_summary_title)(void);		/* Show title for protocol summary) */
   void (*copy_config)(struct proto_config *, struct proto_config *);	/* Copy config from given protocol instance */
 };
 
@@ -217,7 +219,7 @@
 proto_copy_rest(struct proto_config *dest, struct proto_config *src, unsigned size)
 { memcpy(dest + 1, src + 1, size - sizeof(struct proto_config)); }
 
-void proto_cmd_show(struct proto *, unsigned int, int);
+void proto_cmd_show(struct proto *, unsigned int, int, char *);
 void proto_cmd_disable(struct proto *, unsigned int, int);
 void proto_cmd_enable(struct proto *, unsigned int, int);
 void proto_cmd_restart(struct proto *, unsigned int, int);
@@ -226,6 +228,7 @@
 void proto_cmd_mrtdump(struct proto *, unsigned int, int);
 
 void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, unsigned int, int), int restricted, unsigned int arg);
+void proto_apply_show_cmd(struct proto_spec ps, void (* cmd)(struct proto *, unsigned int, int, char *), unsigned int verbose, char *n);
 struct proto *proto_get_named(struct symbol *, struct protocol *);
 
 #define CMD_RELOAD	0
diff -u --recursive proto/bgp/bgp.c.orig proto/bgp/bgp.c
--- proto/bgp/bgp.c.orig	2012-01-10 14:42:47.000000000 +0200
+++ proto/bgp/bgp.c	2012-02-10 15:41:50.000000000 +0200
@@ -1174,6 +1174,34 @@
     }
 }
 
+static void
+bgp_show_summary_title(void)
+{
+	cli_msg(-2002, "Peer\n%12s %-19s %-20s %s", "AS", "Last state change", "Prefixes rcvd/best", "State/Last error" );
+}
+
+static void
+bgp_show_proto_summary(struct proto *P)
+{
+  struct bgp_proto *p = (struct bgp_proto *) P;
+  char rs[20];
+  char ps[256];
+  byte tbuf[TM_DATETIME_BUFFER_SIZE];
+  struct proto_stats *s = &P->stats;
+
+  tm_format_datetime(tbuf, &config->tf_proto, P->last_state_change);
+
+  bsnprintf(rs, sizeof(rs), "%u/%u", s->imp_routes, s->pref_routes);
+  P->proto->get_status(P, ps);
+
+  cli_msg(-1006, "%I\n%12u %-19s %-20s %s",
+               p->cf->remote_ip,
+               p->remote_as,
+               tbuf,
+               rs,
+               ps);
+}
+
 struct protocol proto_bgp = {
   name:			"BGP",
   template:		"bgp%d",
@@ -1187,5 +1215,7 @@
   get_status:		bgp_get_status,
   get_attr:		bgp_get_attr,
   get_route_info:	bgp_get_route_info,
-  show_proto_info:	bgp_show_proto_info
+  show_proto_info:	bgp_show_proto_info,
+  show_summary_title:   bgp_show_summary_title,
+  show_proto_summary:   bgp_show_proto_summary
 };
