mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-17 20:05:53 +00:00
bgpd: general MP/SAFI improvements
This fixes some minor mixups particularly in MPLS-related SAFIs, as well as doing some stylistic changes & adding comments. Signed-off-by: Lou Berger <lberger@labn.net> Reviewed-by: David Lamparter <equinox@opensourcerouting.org> (cherry picked from commit 050defe816e4bd4cac7b028f69e45cb1974ca96d) Conflicts: bgpd/bgp_attr.c bgpd/bgp_attr.h bgpd/bgp_packet.c bgpd/bgp_route.c bgpd/bgp_route.h
This commit is contained in:
parent
005b6bc0ab
commit
93b73dfa17
@ -2208,8 +2208,9 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
||||
stream_putc (s, BGP_ATTR_MP_REACH_NLRI);
|
||||
sizep = stream_get_endp (s);
|
||||
stream_putw (s, 0); /* Marker: Attribute length. */
|
||||
stream_putw (s, afi); /* AFI */
|
||||
stream_putc (s, safi); /* SAFI */
|
||||
|
||||
stream_putw (s, afi);
|
||||
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
|
||||
|
||||
/* Nexthop */
|
||||
switch (nh_afi)
|
||||
@ -2217,7 +2218,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
||||
case AFI_IP:
|
||||
switch (safi)
|
||||
{
|
||||
case SAFI_UNICAST:
|
||||
case SAFI_MULTICAST:
|
||||
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
||||
stream_putc (s, 4);
|
||||
@ -2226,10 +2226,11 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
||||
case SAFI_MPLS_VPN:
|
||||
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
||||
stream_putc (s, 12);
|
||||
stream_putl (s, 0);
|
||||
stream_putl (s, 0); /* RD = 0, per RFC */
|
||||
stream_putl (s, 0);
|
||||
stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
|
||||
break;
|
||||
case SAFI_UNICAST: /* invalid for IPv4 */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2250,6 +2251,28 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
|
||||
if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||
stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
|
||||
}
|
||||
break;
|
||||
case SAFI_MPLS_VPN:
|
||||
{
|
||||
struct attr_extra *attre = attr->extra;
|
||||
|
||||
assert (attr->extra);
|
||||
if (attre->mp_nexthop_len == 16) {
|
||||
stream_putc (s, 24);
|
||||
stream_putl (s, 0); /* RD = 0, per RFC */
|
||||
stream_putl (s, 0);
|
||||
stream_put (s, &attre->mp_nexthop_global, 16);
|
||||
} else if (attre->mp_nexthop_len == 32) {
|
||||
stream_putc (s, 48);
|
||||
stream_putl (s, 0); /* RD = 0, per RFC */
|
||||
stream_putl (s, 0);
|
||||
stream_put (s, &attre->mp_nexthop_global, 16);
|
||||
stream_putl (s, 0); /* RD = 0, per RFC */
|
||||
stream_putl (s, 0);
|
||||
stream_put (s, &attre->mp_nexthop_local, 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2270,24 +2293,27 @@ bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
|
||||
u_char *tag, int addpath_encode,
|
||||
u_int32_t addpath_tx_id)
|
||||
{
|
||||
switch (safi)
|
||||
if (safi == SAFI_MPLS_VPN)
|
||||
{
|
||||
case SAFI_MPLS_VPN:
|
||||
/* addpath TX ID */
|
||||
if (addpath_encode)
|
||||
stream_putl(s, addpath_tx_id);
|
||||
|
||||
/* Tag, RD, Prefix write. */
|
||||
stream_putc (s, p->prefixlen + 88);
|
||||
stream_put (s, tag, 3);
|
||||
stream_put (s, prd->val, 8);
|
||||
stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));
|
||||
break;
|
||||
default:
|
||||
/* Prefix write. */
|
||||
stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id);
|
||||
break;
|
||||
}
|
||||
else
|
||||
stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id);
|
||||
}
|
||||
|
||||
size_t
|
||||
bgp_packet_mpattr_prefix_size (afi_t afi, safi_t safi, struct prefix *p)
|
||||
{
|
||||
int size = PSIZE (p->prefixlen);
|
||||
if (safi == SAFI_MPLS_VPN)
|
||||
size += 88;
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2314,7 +2340,6 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
|
||||
int send_as4_path = 0;
|
||||
int send_as4_aggregator = 0;
|
||||
int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
|
||||
size_t mpattrlen_pos = 0;
|
||||
|
||||
if (! bgp)
|
||||
bgp = peer->bgp;
|
||||
@ -2325,6 +2350,8 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
|
||||
if (p && !((afi == AFI_IP && safi == SAFI_UNICAST) &&
|
||||
!peer_cap_enhe(peer)))
|
||||
{
|
||||
size_t mpattrlen_pos = 0;
|
||||
|
||||
mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
|
||||
(peer_cap_enhe(peer) ? AFI_IP6 : afi),
|
||||
vecarr, attr);
|
||||
@ -2403,7 +2430,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
|
||||
send_as4_path = 1; /* we'll do this later, at the correct place */
|
||||
|
||||
/* Nexthop attribute. */
|
||||
if (afi == AFI_IP && !peer_cap_enhe(peer))
|
||||
if (afi == AFI_IP && safi == SAFI_UNICAST && !peer_cap_enhe(peer))
|
||||
{
|
||||
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
|
||||
{
|
||||
@ -2689,8 +2716,7 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
|
||||
stream_putw (s, 0); /* Length of this attribute. */
|
||||
|
||||
stream_putw (s, afi);
|
||||
safi = (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi;
|
||||
stream_putc (s, safi);
|
||||
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
|
||||
return attrlen_pnt;
|
||||
}
|
||||
|
||||
@ -2718,12 +2744,7 @@ bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
|
||||
void
|
||||
bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt)
|
||||
{
|
||||
bgp_size_t size;
|
||||
|
||||
/* Set MP attribute length. Don't count the (2) bytes used to encode
|
||||
the attr length */
|
||||
size = stream_get_endp (s) - attrlen_pnt - 2;
|
||||
stream_putw_at (s, attrlen_pnt, size);
|
||||
bgp_packet_mpattr_end (s, attrlen_pnt);
|
||||
}
|
||||
|
||||
/* Initialization of attribute. */
|
||||
|
@ -239,6 +239,8 @@ extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
|
||||
struct prefix *p, struct prefix_rd *prd,
|
||||
u_char *tag, int addpath_encode,
|
||||
u_int32_t addpath_tx_id);
|
||||
extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
|
||||
struct prefix *p);
|
||||
extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep);
|
||||
|
||||
extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi,
|
||||
|
@ -206,12 +206,9 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
|
||||
decode_rd_ip (pnt + 5, &rd_ip);
|
||||
break;
|
||||
|
||||
case RD_TYPE_EOI:
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_err ("Invalid RD type %d", type);
|
||||
return -1;
|
||||
zlog_err ("Unknown RD type %d", type);
|
||||
break; /* just report */
|
||||
}
|
||||
|
||||
p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
|
||||
@ -348,14 +345,6 @@ prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
|
||||
snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
|
||||
return buf;
|
||||
}
|
||||
else if (type == RD_TYPE_EOI)
|
||||
{
|
||||
snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
pnt[1], /* LHI */
|
||||
pnt[2], pnt[3], pnt[4], pnt[5], pnt[6], pnt[7]); /* MAC */
|
||||
return buf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#define RD_TYPE_AS 0
|
||||
#define RD_TYPE_IP 1
|
||||
#define RD_TYPE_AS4 2
|
||||
#define RD_TYPE_EOI 0xff00
|
||||
|
||||
#define RD_ADDRSTRLEN 28
|
||||
|
||||
|
@ -2369,6 +2369,7 @@ route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
|
||||
|
||||
/* Set next hop value. */
|
||||
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
|
||||
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
|
||||
}
|
||||
|
||||
return RMAP_OKAY;
|
||||
|
@ -666,7 +666,8 @@ subgroup_update_packet (struct update_subgroup *subgrp)
|
||||
|
||||
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
|
||||
BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||
space_needed = BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen);
|
||||
space_needed = BGP_NLRI_LENGTH +
|
||||
bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);
|
||||
|
||||
/* When remaining space can't include NLRI and it's length. */
|
||||
if (space_remaining < space_needed)
|
||||
@ -675,10 +676,18 @@ subgroup_update_packet (struct update_subgroup *subgrp)
|
||||
/* If packet is empty, set attribute. */
|
||||
if (stream_empty (s))
|
||||
{
|
||||
struct prefix_rd *prd = NULL;
|
||||
u_char *tag = NULL;
|
||||
struct peer *from = NULL;
|
||||
|
||||
if (rn->prn)
|
||||
prd = (struct prefix_rd *) &rn->prn->p;
|
||||
if (binfo)
|
||||
{
|
||||
from = binfo->peer;
|
||||
if (binfo->extra)
|
||||
tag = binfo->extra->tag;
|
||||
}
|
||||
|
||||
/* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
|
||||
* one byte message type.
|
||||
@ -701,8 +710,8 @@ subgroup_update_packet (struct update_subgroup *subgrp)
|
||||
/* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
|
||||
total_attr_len = bgp_packet_attribute (NULL, peer, s,
|
||||
adv->baa->attr, &vecarr,
|
||||
NULL, afi, safi,
|
||||
from, NULL, NULL, 0, 0);
|
||||
&rn->p, afi, safi,
|
||||
from, prd, tag, 0, 0);
|
||||
|
||||
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
|
||||
BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||
|
Loading…
Reference in New Issue
Block a user