On Fri, Jun 17, 2016 at 4:58 AM, Paul Jakma <[email protected]> wrote:

> Hi,
>
> Is it just me, or does this patch leak attr->aspath? I've highlighted the
> bits that made me ask that. Though, to be fair, if so then it looks like
> the old remove-private-as also leaked.
>
> I'd suggest separating lifetime management from the manipulation. Have
> aspath_replace_private_asns and aspath_remove_private_asns just act on the
> given aspath, and have the caller handle lifetime.
>
>
Agreed on both...looks like this is leaking and it seems better to just
have these modify the aspath instead of creating a dup that is modified.

Daniel



> regards,
>
> Paul
>
> On Fri, 11 Dec 2015, Donald Sharp wrote:
>
> +/* Replace all private ASNs with our own ASN */
>> +struct aspath *
>> +aspath_replace_private_asns (struct aspath *aspath, as_t asn)
>> +{
>> +  struct aspath *new;
>> +  struct assegment *seg;
>> +
>> +  new = aspath_dup(aspath);
>>
>      ^^^^^^^^^^^^^^^^^^^^^^^^^
>
>> +  seg = new->segments;
>> +
>> +  while (seg)
>> +    {
>> +      int i;
>> +
>> +      for (i = 0; i < seg->length; i++)
>> +       {
>> +         if (BGP_AS_IS_PRIVATE(seg->as[i]))
>> +            seg->as[i] = asn;
>> +       }
>> +      seg = seg->next;
>> +    }
>> +
>> +  aspath_str_update(new);
>> +  return new;
>> +}
>> +
>> +/* Remove all private ASNs */
>> +struct aspath *
>> +aspath_remove_private_asns (struct aspath *aspath)
>> +{
>> +  struct aspath *new;
>> +  struct assegment *seg;
>> +  struct assegment *new_seg;
>> +  struct assegment *last_new_seg;
>> +  int i;
>> +  int j;
>> +  int public = 0;
>> +
>> +  new = XCALLOC (MTYPE_AS_PATH, sizeof (struct aspath));
>> +
>> +  new_seg = NULL;
>> +  last_new_seg = NULL;
>> +  seg = aspath->segments;
>> +  while (seg)
>> +    {
>> +      public = 0;
>> +      for (i = 0; i < seg->length; i++)
>> +       {
>> +          // ASN is public
>> +         if (!BGP_AS_IS_PRIVATE(seg->as[i]))
>> +            {
>> +                public++;
>> +            }
>> +        }
>> +
>> +      // The entire segment is private so skip it
>> +      if (!public)
>> +        {
>> +          seg = seg->next;
>> +          continue;
>> +        }
>> +
>> +      // The entire segment is public so copy it
>> +      else if (public == seg->length)
>> +        {
>> +          new_seg = assegment_dup (seg);
>> +        }
>> +
>> +      // The segment is a mix of public and private ASNs. Copy as many
>> spots as
>> +      // there are public ASNs then come back and fill in only the
>> public ASNs.
>> +      else
>> +        {
>> +          new_seg = assegment_new (seg->type, public);
>> +          j = 0;
>> +          for (i = 0; i < seg->length; i++)
>> +            {
>> +              // ASN is public
>> +              if (!BGP_AS_IS_PRIVATE(seg->as[i]))
>> +                {
>> +                  new_seg->as[j] = seg->as[i];
>> +                  j++;
>> +                }
>> +            }
>> +        }
>> +
>> +      // This is the first segment so set the aspath segments pointer to
>> this one
>> +      if (!last_new_seg)
>> +        new->segments = new_seg;
>> +      else
>> +        last_new_seg->next = new_seg;
>> +
>> +      last_new_seg = new_seg;
>> +      seg = seg->next;
>> +    }
>> +
>> +  aspath_str_update(new);
>> +  return new;
>> +}
>> +
>>
>
> +/* If this is an EBGP peer with remove-private-AS */
>> +static void
>> +bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
>> +                           struct peer *peer, struct attr *attr)
>> +{
>> +  if (peer->sort == BGP_PEER_EBGP &&
>> +      peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS))
>> +    {
>> +      // Take action on the entire aspath
>> +      if (peer_af_flag_check (peer, afi, safi,
>> PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
>> +        {
>> +          if (peer_af_flag_check (peer, afi, safi,
>> PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
>> +            attr->aspath = aspath_replace_private_asns (attr->aspath,
>> bgp->as);
>>
>                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>> +
>> +          // The entire aspath consists of private ASNs so create an
>> empty aspath
>> +          else if (aspath_private_as_check (attr->aspath))
>> +            attr->aspath = aspath_empty_get ();
>>
>                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>> +
>> +          // There are some public and some private ASNs, remove the
>> private ASNs
>> +          else
>> +            attr->aspath = aspath_remove_private_asns (attr->aspath);
>>
>                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>> +        }
>> +
>> +      // 'all' was not specified so the entire aspath must be private
>> ASNs
>> +      // for us to do anything
>> +      else if (aspath_private_as_check (attr->aspath))
>> +        {
>> +          if (peer_af_flag_check (peer, afi, safi,
>> PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
>> +            attr->aspath = aspath_replace_private_asns (attr->aspath,
>> bgp->as);
>>
>                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>> +          else
>> +            attr->aspath = aspath_empty_get ();
>>
>                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>> +        }
>>
>
> -
>> -  /* If this is EBGP peer and remove-private-AS is set.  */
>> -  if (rsclient->sort == BGP_PEER_EBGP
>> -      && peer_af_flag_check (rsclient, afi, safi,
>> PEER_FLAG_REMOVE_PRIVATE_AS)
>> -      && aspath_private_as_check (attr->aspath))
>> -    attr->aspath = aspath_empty_get ();
>> +  bgp_peer_remove_private_as(bgp, afi, safi, rsclient, attr);
>>
>> regards,
> --
> Paul Jakma | [email protected] | @pjakma | Key ID: 0xD86BF79464A2FF6A
> Fortune:
> It is impossible to travel faster than light, and certainly not desirable,
> as one's hat keeps blowing off.
>                 -- Woody Allen
>
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to