diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/bgp_attr.c | 52 | ||||
| -rw-r--r-- | bgpd/bgp_attr.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_dump.c | 12 | 
3 files changed, 55 insertions, 11 deletions
| diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 480bb912..91a0e07c 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1738,7 +1738,8 @@ bgp_attr_init ()  /* Make attribute packet. */  void -bgp_dump_routes_attr (struct stream *s, struct attr *attr) +bgp_dump_routes_attr (struct stream *s, struct attr *attr,  +                      struct prefix *prefix)  {    unsigned long cp;    unsigned long len; @@ -1773,10 +1774,18 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr)    stream_put (s, aspath->data, aspath->length);    /* Nexthop attribute. */ -  stream_putc (s, BGP_ATTR_FLAG_TRANS); -  stream_putc (s, BGP_ATTR_NEXT_HOP); -  stream_putc (s, 4); -  stream_put_ipv4 (s, attr->nexthop.s_addr); +  /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */ +  if(prefix != NULL +#ifdef HAVE_IPV6 +     && prefix->family != AF_INET6 +#endif /* HAVE_IPV6 */ +     ) +    { +      stream_putc (s, BGP_ATTR_FLAG_TRANS); +      stream_putc (s, BGP_ATTR_NEXT_HOP); +      stream_putc (s, 4); +      stream_put_ipv4 (s, attr->nexthop.s_addr); +    }    /* MED attribute. */    if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) @@ -1832,6 +1841,39 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr)        stream_put (s, attr->community->val, attr->community->size * 4);      } +#ifdef HAVE_IPV6 +  /* Add a MP_NLRI attribute to dump the IPv6 next hop */ +  if(prefix != NULL && prefix->family == AF_INET6 &&  +     (attr->mp_nexthop_len == 16 || attr->mp_nexthop_len == 32) ) +    { +      int sizep; + +      stream_putc(s, BGP_ATTR_FLAG_OPTIONAL); +      stream_putc(s, BGP_ATTR_MP_REACH_NLRI); +      sizep = stream_get_putp (s); + +      /* MP header */ +      stream_putc (s, 0);		/* Length of this attribute. */ +      stream_putw(s, AFI_IP6);		/* AFI */ +      stream_putc(s, SAFI_UNICAST);	/* SAFI */ + +      /* Next hop */ +      stream_putc(s, attr->mp_nexthop_len); +      stream_put(s, &attr->mp_nexthop_global, 16); +      if(attr->mp_nexthop_len == 32) +        stream_put(s, &attr->mp_nexthop_local, 16); + +      /* SNPA */ +      stream_putc(s, 0); + +      /* Prefix */ +      stream_put_prefix(s, prefix); + +      /* Set MP attribute length. */ +      stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1); +    } +#endif /* HAVE_IPV6 */ +    /* Return total size of attribute. */    len = stream_get_putp (s) - cp - 2;    stream_putw_at (s, cp, len); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index e44ff3a3..2bcbbf37 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -114,7 +114,7 @@ struct attr *bgp_attr_default_intern (u_char);  struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char, struct aspath *, struct community *, int as_set);  bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, struct stream *, struct attr *, struct prefix *, afi_t, safi_t, struct peer *, struct prefix_rd *, u_char *);  bgp_size_t bgp_packet_withdraw (struct peer *peer, struct stream *s, struct prefix *p, afi_t, safi_t, struct prefix_rd *, u_char *); -void bgp_dump_routes_attr (struct stream *, struct attr *); +void bgp_dump_routes_attr (struct stream *, struct attr *, struct prefix *);  unsigned int attrhash_key_make (struct attr *);  int attrhash_cmp (struct attr *, struct attr *);  void attr_show_all (struct vty *); diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index 516e9b25..e3c62814 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -236,7 +236,7 @@ bgp_dump_routes_entry (struct prefix *p, struct bgp_info *info, int afi,  	  stream_putw (obuf, peer->as);  	  /* Dump attribute. */ -	  bgp_dump_routes_attr (obuf, attr); +	  bgp_dump_routes_attr (obuf, attr, NULL);  	}        else  	{ @@ -246,7 +246,7 @@ bgp_dump_routes_entry (struct prefix *p, struct bgp_info *info, int afi,  	  stream_putc (obuf, p->prefixlen);  	  plen = PSIZE (p->prefixlen);  	  stream_put (obuf, &p->u.prefix4, plen); -	  bgp_dump_routes_attr (obuf, attr); +	  bgp_dump_routes_attr (obuf, attr, NULL);  	}      }  #ifdef HAVE_IPV6 @@ -272,7 +272,7 @@ bgp_dump_routes_entry (struct prefix *p, struct bgp_info *info, int afi,  	  stream_putw (obuf, peer->as);  	  /* Dump attribute. */ -	  bgp_dump_routes_attr (obuf, attr); +	  bgp_dump_routes_attr (obuf, attr, p);  	}        else  	{ @@ -330,7 +330,9 @@ bgp_dump_interval_func (struct thread *t)        if (bgp_dump->type == BGP_DUMP_ROUTES)  	{  	  bgp_dump_routes_func (AFI_IP); +#ifdef HAVE_IPV6  	  bgp_dump_routes_func (AFI_IP6); +#endif /* HAVE_IPV6 */  	  /* Close the file now. For a RIB dump there's no point in leaving  	   * it open until the next scheduled dump starts. */  	  fclose(bgp_dump->fp); bgp_dump->fp = NULL; @@ -354,7 +356,7 @@ bgp_dump_common (struct stream *obuf, struct peer *peer)    stream_putw (obuf, peer->as);    stream_putw (obuf, peer->local_as); -  if (peer->afc[AFI_IP][SAFI_UNICAST]) +  if (peer->su.sa.sa_family == AF_INET)      {        stream_putw (obuf, peer->ifindex);        stream_putw (obuf, AFI_IP); @@ -367,7 +369,7 @@ bgp_dump_common (struct stream *obuf, struct peer *peer)  	stream_put (obuf, empty, IPV4_MAX_BYTELEN);      }  #ifdef HAVE_IPV6 -  else if (peer->afc[AFI_IP6][SAFI_UNICAST]) +  else if (peer->su.sa.sa_family == AF_INET6)      {        /* Interface Index and Address family. */        stream_putw (obuf, peer->ifindex); | 
