[quagga-dev 10943] Re: Assert in bgp_attr.c

Milan Kocian milon at wq.cz
Wed Dec 4 08:59:31 GMT 2013


On Tue, Dec 03, 2013 at 06:38:19PM +0100, David Lamparter wrote:
> On Fri, Nov 29, 2013 at 04:53:15PM +0100, Milan Kocian wrote:
> > I get this assert when I try to add extended community on received routes which
> > have ext attributes set. When received route has no ext community
> > there is no problem with adding new ext. community.
> 
> Urgh.  I think I know what the problem is... and it's quite ugly
> actually:
> 
> > 2013/11/29 16:27:57 BGP: Assertion `ret != ((void *)0)' failed in file
> > bgp_attr.c, line 693, function bgp_attr_unintern
> 
> This is indicating that the attr could not be found in the caching-index
> attrhash.  If I'm not completely mistaken, the reason for this is that
> bgp_routemap.c:1559 just modifies the existing attr, without copying it
> or rehashing.  This may sound innocent enough, but it actually means
> that ALL routes that share this cached attr instance get the change
> applied!  Meaning, we're causing other routes to have broken attributes.
> Whoops.
> 
> I'll mail a patch for this in a bit,
> 
> 
> David
> 

Hi David,

many thanks for answer. Here is desired config (I have simple crash test
config example :-)). I have other nice crashes related to the setting
extcommunities in route-map ... Please read new notes below.

Sender side config (it sends routes which crash on crash side):

!
hostname bgpd2
password zz
log file /var/log/quagga/bgpd.log
service advanced-vty
!
router bgp 65522
 bgp router-id 95.168.200.26
 no bgp default ipv4-unicast
 network 193.178.166.0/24 route-map 193_178_166_0
 network 195.128.132.0/24 route-map 195_128_132_0
 network 195.189.224.0/24 route-map 195_189_224_0
 neighbor 95.168.200.29 remote-as 61195
 neighbor 95.168.200.29 activate
 neighbor 95.168.200.29 soft-reconfiguration inbound
!
route-map 195_128_132_0 permit 10
 set community 1:1085 15669:43561 43561:8899 60777:777 64700:43561 65400:0 65400:65400
 set as-path prepend 43561 8717 197719
 set extcommunity rt 43561:1000 43561:2000 43561:3000 43561:60000
!
route-map 193_178_166_0 permit 10
 set community 1:1085 43561:11111 60777:777 64700:43561 65400:0 65400:65400
 set as-path prepend 43561 12962
 set extcommunity rt 43561:1000 43561:2000 43561:3000 43561:60000
!
route-map 195_189_224_0 permit 10
 set community 1:1085 43561:11111 60777:777 64700:43561 65400:0 65400:65400
 set as-path prepend 43561 39683 39683 39683
 set extcommunity rt 100:100 43561:1000 43561:2000 43561:3000 43561:60000
!
line vty
 exec-timeout 0 0


Crashed side config:

!
! Zebra configuration saved from vty
!   2013/11/27 11:00:54
!
hostname rs-bgpd
password zz
enable password zzz
log file /var/log/quagga/bgpd.log
debug bgp filters
debug bgp events
debug bgp updates
debug bgp fsm
!
!bgp multiple-instance
!
router bgp 61195
 bgp router-id 91.213.211.2
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 95.168.200.26 remote-as 65522
 neighbor 95.168.200.26 description AS65522
 neighbor 95.168.200.26 activate
! neighbor 95.168.200.26 soft-reconfiguration inbound
 neighbor 95.168.200.26 maximum-prefix 20000
 neighbor 95.168.200.26 route-map AS65522-export in
!
route-map AS65522-export permit 40
 set community additive 10:10
 set community additive 61195:65522
 set extcommunity soo 61195:65522
 on-match next
!
line vty
 exec-timeout 0 0


Some new discoveries I got from my tests:

When 'neighbor 95.168.200.26 soft-reconfiguration inbound' is disabled,
bgpd crashes immediatelly on signal 11:

*** glibc detected *** /root/qgit/bgpd/.libs/bgpd: invalid fastbin entry (free): 0x0000555555993560 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7ffff6fa8d76]
/lib/x86_64-linux-gnu/libc.so.6(+0x7c7c3)[0x7ffff6fae7c3]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0xf0)[0x7ffff6faec60]
/usr/lib/libzebra.so.0(zrealloc+0x1f)[0x7ffff7ba5c80]
/root/qgit/bgpd/.libs/bgpd(+0x48516)[0x55555559c516]
/root/qgit/bgpd/.libs/bgpd(+0x48717)[0x55555559c717]
/root/qgit/bgpd/.libs/bgpd(+0x48752)[0x55555559c752]
/root/qgit/bgpd/.libs/bgpd(+0x281e6)[0x55555557c1e6]
/root/qgit/bgpd/.libs/bgpd(+0x42910)[0x555555596910]
/root/qgit/bgpd/.libs/bgpd(bgp_read+0xac4)[0x55555559882c]
/usr/lib/libzebra.so.0(thread_call+0x8f)[0x7ffff7ba4910]
/root/qgit/bgpd/.libs/bgpd(main+0x3f2)[0x55555556f775]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7ffff6f50ead]
/root/qgit/bgpd/.libs/bgpd(+0x1b7c9)[0x55555556f7c9]

GDB backtrace:

Program received signal SIGABRT, Aborted.
0x00007ffff6f64475 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) 
(gdb) bt
#0  0x00007ffff6f64475 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff6f676f0 in *__GI_abort () at abort.c:92
#2  0x00007ffff6f9f52b in __libc_message (do_abort=<optimized out>, fmt=<optimized out>)
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3  0x00007ffff6fa8d76 in malloc_printerr (action=3, str=0x7ffff707dbc9 "invalid fastbin entry (free)", 
    ptr=<optimized out>) at malloc.c:6283
#4  0x00007ffff6fae7c3 in _int_realloc (av=0x7ffff72b7e60, oldp=0x555555993550, oldsize=48, nb=64)
    at malloc.c:5341
#5  0x00007ffff6faec60 in *__GI___libc_realloc (oldmem=0x555555993560, bytes=56) at malloc.c:3821
#6  0x00007ffff7ba5c80 in zrealloc (type=type at entry=101, ptr=ptr at entry=0x555555993560, size=size at entry=56)
    at memory.c:111
#7  0x000055555559c516 in ecommunity_ecom2str (format=2, ecom=0x555555993740) at bgp_ecommunity.c:634
#8  ecommunity_ecom2str (ecom=0x555555993740, format=2) at bgp_ecommunity.c:589
#9  0x000055555559c717 in ecommunity_intern (ecom=0x555555993740) at bgp_ecommunity.c:206
#10 0x000055555559c752 in ecommunity_parse (pnt=<optimized out>, length=length at entry=32)
    at bgp_ecommunity.c:142
#11 0x000055555557c1e6 in bgp_attr_ext_communities (args=0x7fffffffc5a8) at bgp_attr.c:1647
#12 bgp_attr_parse (peer=peer at entry=0x55555597f3d0, attr=attr at entry=0x7fffffffc680, size=size at entry=106, 
    mp_update=mp_update at entry=0x7fffffffc650, mp_withdraw=mp_withdraw at entry=0x7fffffffc668) at bgp_attr.c:1907
#13 0x0000555555596910 in bgp_update_receive (peer=peer at entry=0x55555597f3d0, size=size at entry=114)
    at bgp_packet.c:1650
#14 0x000055555559882c in bgp_read (thread=<optimized out>) at bgp_packet.c:2536
!
#15 0x00007ffff7ba4910 in thread_call (thread=thread at entry=0x7fffffffea18) at thread.c:1258
#16 0x000055555556f775 in main (argc=5, argv=0x7fffffffebc8) at bgp_main.c:466
(gdb) q
A debugging session is active.


When I enable 'neighbor 95.168.200.26 soft-reconfiguration inbound', routes
are accepted and bgpd is running. Until I do 'clear ip bgp * out' on sender side.

GDB backtrace:

Program received signal SIGABRT, Aborted.
0x00007ffff6f64475 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) 
(gdb) 
(gdb) bt
#0  0x00007ffff6f64475 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff6f676f0 in *__GI_abort () at abort.c:92
#2  0x00007ffff7bafd7b in _zlog_assert_failed (assertion=assertion at entry=0x5555555b6469 "ret != ((void *)0)", 
    file=file at entry=0x5555555b645e "bgp_attr.c", line=line at entry=693, 
    function=function at entry=0x5555555b6e50 "bgp_attr_unintern") at log.c:619
#3  0x000055555557b2ec in bgp_attr_unintern (pattr=pattr at entry=0x5555559936f8) at bgp_attr.c:693
#4  0x00005555555a0ace in bgp_adj_in_set (rn=rn at entry=0x555555993660, peer=peer at entry=0x55555597f3d0, 
    attr=attr at entry=0x7fffffffc680) at bgp_advertise.c:342
#5  0x00005555555884e1 in bgp_update_main (peer=peer at entry=0x55555597f3d0, p=p at entry=0x7fffffffa5b8, 
    attr=attr at entry=0x7fffffffc680, afi=afi at entry=1, safi=safi at entry=1 '\001', type=type at entry=9, sub_type=0, 
    prd=0x0, tag=0x0, soft_reconfig=0) at bgp_route.c:2077
#6  0x0000555555588fda in bgp_update (peer=peer at entry=0x55555597f3d0, p=p at entry=0x7fffffffa5b8, 
    attr=attr at entry=0x7fffffffc680, afi=1, safi=1 '\001', type=type at entry=9, sub_type=0, prd=0x0, tag=0x0, 
    soft_reconfig=0) at bgp_route.c:2385
#7  0x0000555555589231 in bgp_nlri_parse (peer=peer at entry=0x55555597f3d0, attr=attr at entry=0x7fffffffc680, 
    packet=packet at entry=0x7fffffffc620) at bgp_route.c:3151
#8  0x0000555555596a9d in bgp_update_receive (peer=peer at entry=0x55555597f3d0, size=size at entry=106)
    at bgp_packet.c:1716
#9  0x000055555559882c in bgp_read (thread=<optimized out>) at bgp_packet.c:2536
#10 0x00007ffff7ba4910 in thread_call (thread=thread at entry=0x7fffffffea18) at thread.c:1258
#11 0x000055555556f775 in main (argc=5, argv=0x7fffffffebc8) at bgp_main.c:466


There is no problem when:

1. received routes have no extcomms set (then I can set extcomms in routemaps 
   on crash side without problem)
2. when received routes have extcomms and I don't set extcomms on crash side

So problematic case is when received routes have extcomms and I am adding
my extcomms in routemap.

IMHO problem is in this path in bgp_routemap.c (but I can't see
any problem there :-( ). But may be I am completely wrong :-).

static route_map_result_t
route_set_ecommunity_soo (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
{
  struct ecommunity *ecom, *old_ecom, *new_ecom;
  struct bgp_info *bgp_info;

  if (type == RMAP_BGP)
    {
      ecom = rule;
      bgp_info = object;

      if (! ecom)
        return RMAP_OKAY;

      old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;

>>>      if (old_ecom)
>>>        new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
      else
        new_ecom = ecommunity_dup (ecom);

      bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);

>>>     if (old_ecom)
>>>        ecommunity_unintern (&old_ecom);

      bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
    }
  return RMAP_OKAY;
}


Best regards,

-- 
Milan Kocian




More information about the Quagga-dev mailing list