Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a number of VPN/Encap SAFI related issues (no VRF CLI changes) #83

Merged
5 changes: 4 additions & 1 deletion bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2643,6 +2643,8 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
stream_putw (s, afi);
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);

if (nh_afi == AFI_MAX)
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
/* Nexthop */
switch (nh_afi)
{
Expand Down Expand Up @@ -2894,7 +2896,8 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
size_t mpattrlen_pos = 0;

mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
(peer_cap_enhe(peer) ? AFI_IP6 : afi),
(peer_cap_enhe(peer) ? AFI_IP6 :
AFI_MAX), /* get from NH */
vecarr, attr);
bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
addpath_encode, addpath_tx_id);
Expand Down
179 changes: 108 additions & 71 deletions bgpd/bgp_route.c

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions bgpd/bgp_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ struct bgp_static
u_char tag[3];
};

#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \
((nhlen) < IPV4_MAX_BYTELEN ? 0 : \
((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))

#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
(! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)) && \
(attr)->extra && ((attr)->extra->mp_nexthop_len == 16 || \
Expand Down
57 changes: 36 additions & 21 deletions bgpd/bgp_updgrp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,20 @@ 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)
{
nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
if (peer_cap_enhe(peer))
nhafi = AFI_IP6;
if (paf->safi == SAFI_MPLS_VPN && /* if VPN && not global */
nhlen != BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
nhafi = AFI_MAX; /* no change allowed */
}

if (nhafi == AFI_IP)
{
struct in_addr v4nh, *mod_v4nh;
int nh_modified = 0;
Expand Down Expand Up @@ -462,23 +472,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",
PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
peer->host, inet_ntoa (*mod_v4nh));

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),
(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;
Expand Down Expand Up @@ -515,17 +526,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;
Expand All @@ -534,25 +546,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" : ""));
}
}
}
Expand Down Expand Up @@ -747,7 +761,8 @@ subgroup_update_packet (struct update_subgroup *subgrp)

if (stream_empty (snlri))
mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi,
(peer_cap_enhe(peer) ? AFI_IP6 : afi),
(peer_cap_enhe(peer) ? AFI_IP6 :
AFI_MAX), /* get from NH */
&vecarr, adv->baa->attr);
bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, tag,
addpath_encode, addpath_tx_id);
Expand Down
8 changes: 4 additions & 4 deletions bgpd/bgpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -7142,9 +7142,9 @@ bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
else if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv4 multicast");
else if (safi == SAFI_MPLS_VPN)
vty_out (vty, "vpnv4");
vty_out (vty, "ipv4 vpn");
else if (safi == SAFI_ENCAP)
vty_out (vty, "encap");
vty_out (vty, "ipv4 encap");
}
else if (afi == AFI_IP6)
{
Expand All @@ -7153,9 +7153,9 @@ bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
else if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv6 multicast");
else if (safi == SAFI_MPLS_VPN)
vty_out (vty, "vpnv6");
vty_out (vty, "ipv6 vpn");
else if (safi == SAFI_ENCAP)
vty_out (vty, "encapv6");
vty_out (vty, "ipv6 encap");
}

vty_out (vty, "%s", VTY_NEWLINE);
Expand Down
3 changes: 1 addition & 2 deletions bgpd/rfapi/rfapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,6 @@ add_vnc_route (
bgp_attr_extra_free (&attr);
return;
}
nexthop = un_addr; /* UN used as MPLS NLRI nexthop */
}

if (local_pref)
Expand Down Expand Up @@ -2778,7 +2777,7 @@ rfapi_register (
NULL,
action == RFAPI_REGISTER_KILL);

if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &adv_tunnel))
if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &prd, &adv_tunnel))
{
if (adv_tunnel)
rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime);
Expand Down
Loading