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)
{
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);
#ifdef HAVE_IPV6
#define NEXTHOP_IS_V6 (\
- (safi != SAFI_ENCAP && \
+ (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
(p->family == AF_INET6 || peer_cap_enhe(peer))) || \
- (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
+ ((safi == SAFI_ENCAP || safi != SAFI_MPLS_VPN) &&\
+ attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
/* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
* the peer (group) is configured to receive link-local nexthop unchanged
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 || \
nhlen = stream_getc_from (s, vec->offset);
if (paf->afi == AFI_IP || paf->afi == AFI_IP6)
{
- if (nhlen < IPV6_MAX_BYTELEN && !peer_cap_enhe(peer))
- nhafi = AFI_IP;
- else
+ nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
+ if (peer_cap_enhe(peer))
nhafi = AFI_IP6;
- if (paf->safi == SAFI_MPLS_VPN && /* if VPN */
- nhlen != 48) /* and ! GLOBAL_AND_LL */
+ 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 (bgp_debug_update(peer, NULL, NULL, 0))
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s%s",
- PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
+ PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
peer->host, inet_ntoa (*mod_v4nh),
(nhlen == 12 ? " and RD" : ""));
}
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);