diff options
author | Lou Berger <lberger@labn.net> | 2017-01-14 15:46:54 +0100 |
---|---|---|
committer | Lou Berger <lberger@labn.net> | 2017-01-17 20:59:10 +0100 |
commit | 9857dafd6254f52bbab507932d2f7e65423389a4 (patch) | |
tree | 80e30be3a5e3e6ce0e47b2c3141016f0d4bb5ada /bgpd/bgp_updgrp_packet.c | |
parent | bgpd: partial revert of vpn/encap safi show changes (Issue #14) (diff) | |
download | frr-9857dafd6254f52bbab507932d2f7e65423389a4.tar.xz frr-9857dafd6254f52bbab507932d2f7e65423389a4.zip |
bgpd: fix RD stomping by update group code (Issue #71)
Signed-off-by: Lou Berger <lberger@labn.net>
Diffstat (limited to '')
-rw-r--r-- | bgpd/bgp_updgrp_packet.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index e18ba235c..20bf28967 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -418,10 +418,21 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf) if (CHECK_FLAG (vec->flags, BPKT_ATTRVEC_FLAGS_UPDATED)) { u_int8_t nhlen; + afi_t nhafi = AFI_MAX; /* NH AFI is based on nhlen! */ int route_map_sets_nh; nhlen = stream_getc_from (s, vec->offset); - - if (paf->afi == AFI_IP && !peer_cap_enhe(peer)) + if (paf->afi == AFI_IP || paf->afi == AFI_IP6) + { + if (nhlen < IPV6_MAX_BYTELEN && !peer_cap_enhe(peer)) + nhafi = AFI_IP; + else + nhafi = AFI_IP6; + if (paf->safi == SAFI_MPLS_VPN && /* if VPN */ + nhlen != 48) /* and ! GLOBAL_AND_LL */ + nhafi = AFI_MAX; /* no change allowed */ + } + + if (nhafi == AFI_IP) { struct in_addr v4nh, *mod_v4nh; int nh_modified = 0; @@ -462,23 +473,24 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf) (bgp_multiaccess_check_v4 (v4nh, peer) == 0) && !CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) && - !peer_af_flag_check (peer, paf->afi, paf->safi, + !peer_af_flag_check (peer, nhafi, paf->safi, PEER_FLAG_NEXTHOP_UNCHANGED)) { + /* NOTE: not handling case where NH has new AFI */ mod_v4nh = &peer->nexthop.v4; nh_modified = 1; } - if (nh_modified) - stream_put_in_addr_at (s, vec->offset + 1, mod_v4nh); + if (nh_modified) /* allow for VPN RD */ + stream_put_in_addr_at (s, vec->offset + 1 + nhlen - 4, mod_v4nh); if (bgp_debug_update(peer, NULL, NULL, 0)) - zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s", + zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s%s", PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id, - peer->host, inet_ntoa (*mod_v4nh)); - + peer->host, inet_ntoa (*mod_v4nh), + (nhlen == 12 ? " and RD" : "")); } - else if (paf->afi == AFI_IP6 || peer_cap_enhe(peer)) + else if (nhafi == AFI_IP6) { struct in6_addr v6nhglobal, *mod_v6nhg; struct in6_addr v6nhlocal, *mod_v6nhl; @@ -515,17 +527,18 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf) else if (peer->sort == BGP_PEER_EBGP && !CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) && - !peer_af_flag_check (peer, paf->afi, paf->safi, + !peer_af_flag_check (peer, nhafi, paf->safi, PEER_FLAG_NEXTHOP_UNCHANGED)) { + /* NOTE: not handling case where NH has new AFI */ mod_v6nhg = &peer->nexthop.v6_global; gnh_modified = 1; } - if (nhlen == 32) + if (nhlen == 32 || nhlen == 48) /* 48 == VPN */ { - stream_get_from (&v6nhlocal, s, vec->offset + 1 + 16, 16); + stream_get_from (&v6nhlocal, s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), IPV6_MAX_BYTELEN); if (IN6_IS_ADDR_UNSPECIFIED (&v6nhlocal)) { mod_v6nhl = &peer->nexthop.v6_local; @@ -534,25 +547,27 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf) } if (gnh_modified) - stream_put_in6_addr_at (s, vec->offset + 1, mod_v6nhg); + stream_put_in6_addr_at (s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), mod_v6nhg); if (lnh_modified) - stream_put_in6_addr_at (s, vec->offset + 1 + 16, mod_v6nhl); + stream_put_in6_addr_at (s, vec->offset + 1 + (nhlen-IPV6_MAX_BYTELEN), mod_v6nhl); if (bgp_debug_update(peer, NULL, NULL, 0)) { - if (nhlen == 32) - zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthops %s, %s", + if (nhlen == 32 || nhlen == 48) + zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthops %s, %s%s", PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id, peer->host, inet_ntop (AF_INET6, mod_v6nhg, buf, BUFSIZ), - inet_ntop (AF_INET6, mod_v6nhl, buf2, BUFSIZ)); + inet_ntop (AF_INET6, mod_v6nhl, buf2, BUFSIZ), + (nhlen == 48 ? " and RD" : "")); else - zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthop %s", + zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthop %s%s", PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id, peer->host, - inet_ntop (AF_INET6, mod_v6nhg, buf, BUFSIZ)); + inet_ntop (AF_INET6, mod_v6nhg, buf, BUFSIZ), + (nhlen == 24 ? " and RD" : "")); } } } |