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);
|
stream_putc (s, BGP_ATTR_MP_REACH_NLRI);
|
||||||
sizep = stream_get_endp (s);
|
sizep = stream_get_endp (s);
|
||||||
stream_putw (s, 0); /* Marker: Attribute length. */
|
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 */
|
/* Nexthop */
|
||||||
switch (nh_afi)
|
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:
|
case AFI_IP:
|
||||||
switch (safi)
|
switch (safi)
|
||||||
{
|
{
|
||||||
case SAFI_UNICAST:
|
|
||||||
case SAFI_MULTICAST:
|
case SAFI_MULTICAST:
|
||||||
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
||||||
stream_putc (s, 4);
|
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:
|
case SAFI_MPLS_VPN:
|
||||||
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
|
||||||
stream_putc (s, 12);
|
stream_putc (s, 12);
|
||||||
stream_putl (s, 0);
|
stream_putl (s, 0); /* RD = 0, per RFC */
|
||||||
stream_putl (s, 0);
|
stream_putl (s, 0);
|
||||||
stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
|
stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
|
||||||
break;
|
break;
|
||||||
|
case SAFI_UNICAST: /* invalid for IPv4 */
|
||||||
default:
|
default:
|
||||||
break;
|
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)
|
if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
||||||
stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
|
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:
|
default:
|
||||||
break;
|
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_char *tag, int addpath_encode,
|
||||||
u_int32_t addpath_tx_id)
|
u_int32_t addpath_tx_id)
|
||||||
{
|
{
|
||||||
switch (safi)
|
if (safi == SAFI_MPLS_VPN)
|
||||||
{
|
{
|
||||||
case SAFI_MPLS_VPN:
|
|
||||||
/* addpath TX ID */
|
|
||||||
if (addpath_encode)
|
if (addpath_encode)
|
||||||
stream_putl(s, addpath_tx_id);
|
stream_putl(s, addpath_tx_id);
|
||||||
|
|
||||||
/* Tag, RD, Prefix write. */
|
/* Tag, RD, Prefix write. */
|
||||||
stream_putc (s, p->prefixlen + 88);
|
stream_putc (s, p->prefixlen + 88);
|
||||||
stream_put (s, tag, 3);
|
stream_put (s, tag, 3);
|
||||||
stream_put (s, prd->val, 8);
|
stream_put (s, prd->val, 8);
|
||||||
stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));
|
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
|
void
|
||||||
@ -2314,7 +2340,6 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
|
|||||||
int send_as4_path = 0;
|
int send_as4_path = 0;
|
||||||
int send_as4_aggregator = 0;
|
int send_as4_aggregator = 0;
|
||||||
int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
|
int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
|
||||||
size_t mpattrlen_pos = 0;
|
|
||||||
|
|
||||||
if (! bgp)
|
if (! bgp)
|
||||||
bgp = peer->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) &&
|
if (p && !((afi == AFI_IP && safi == SAFI_UNICAST) &&
|
||||||
!peer_cap_enhe(peer)))
|
!peer_cap_enhe(peer)))
|
||||||
{
|
{
|
||||||
|
size_t mpattrlen_pos = 0;
|
||||||
|
|
||||||
mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
|
mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
|
||||||
(peer_cap_enhe(peer) ? AFI_IP6 : afi),
|
(peer_cap_enhe(peer) ? AFI_IP6 : afi),
|
||||||
vecarr, attr);
|
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 */
|
send_as4_path = 1; /* we'll do this later, at the correct place */
|
||||||
|
|
||||||
/* Nexthop attribute. */
|
/* 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))
|
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, 0); /* Length of this attribute. */
|
||||||
|
|
||||||
stream_putw (s, afi);
|
stream_putw (s, afi);
|
||||||
safi = (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi;
|
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
|
||||||
stream_putc (s, safi);
|
|
||||||
return attrlen_pnt;
|
return attrlen_pnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2718,12 +2744,7 @@ bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
|
|||||||
void
|
void
|
||||||
bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt)
|
bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt)
|
||||||
{
|
{
|
||||||
bgp_size_t size;
|
bgp_packet_mpattr_end (s, attrlen_pnt);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialization of attribute. */
|
/* 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,
|
struct prefix *p, struct prefix_rd *prd,
|
||||||
u_char *tag, int addpath_encode,
|
u_char *tag, int addpath_encode,
|
||||||
u_int32_t addpath_tx_id);
|
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 void bgp_packet_mpattr_end(struct stream *s, size_t sizep);
|
||||||
|
|
||||||
extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi,
|
extern size_t bgp_packet_mpunreach_start (struct stream *s, afi_t afi,
|
||||||
|
@ -206,13 +206,10 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
|
|||||||
decode_rd_ip (pnt + 5, &rd_ip);
|
decode_rd_ip (pnt + 5, &rd_ip);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RD_TYPE_EOI:
|
default:
|
||||||
break;
|
zlog_err ("Unknown RD type %d", type);
|
||||||
|
break; /* just report */
|
||||||
default:
|
}
|
||||||
zlog_err ("Invalid RD type %d", type);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
|
p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
|
||||||
memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
|
memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
|
||||||
@ -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);
|
snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
|
||||||
return buf;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#define RD_TYPE_AS 0
|
#define RD_TYPE_AS 0
|
||||||
#define RD_TYPE_IP 1
|
#define RD_TYPE_IP 1
|
||||||
#define RD_TYPE_AS4 2
|
#define RD_TYPE_AS4 2
|
||||||
#define RD_TYPE_EOI 0xff00
|
|
||||||
|
|
||||||
#define RD_ADDRSTRLEN 28
|
#define RD_ADDRSTRLEN 28
|
||||||
|
|
||||||
|
@ -2369,6 +2369,7 @@ route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
|
|||||||
|
|
||||||
/* Set next hop value. */
|
/* 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_global_in = *address;
|
||||||
|
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RMAP_OKAY;
|
return RMAP_OKAY;
|
||||||
|
@ -666,7 +666,8 @@ subgroup_update_packet (struct update_subgroup *subgrp)
|
|||||||
|
|
||||||
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
|
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
|
||||||
BGP_MAX_PACKET_SIZE_OVERFLOW;
|
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. */
|
/* When remaining space can't include NLRI and it's length. */
|
||||||
if (space_remaining < space_needed)
|
if (space_remaining < space_needed)
|
||||||
@ -675,10 +676,18 @@ subgroup_update_packet (struct update_subgroup *subgrp)
|
|||||||
/* If packet is empty, set attribute. */
|
/* If packet is empty, set attribute. */
|
||||||
if (stream_empty (s))
|
if (stream_empty (s))
|
||||||
{
|
{
|
||||||
|
struct prefix_rd *prd = NULL;
|
||||||
|
u_char *tag = NULL;
|
||||||
struct peer *from = NULL;
|
struct peer *from = NULL;
|
||||||
|
|
||||||
|
if (rn->prn)
|
||||||
|
prd = (struct prefix_rd *) &rn->prn->p;
|
||||||
if (binfo)
|
if (binfo)
|
||||||
from = binfo->peer;
|
{
|
||||||
|
from = binfo->peer;
|
||||||
|
if (binfo->extra)
|
||||||
|
tag = binfo->extra->tag;
|
||||||
|
}
|
||||||
|
|
||||||
/* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
|
/* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
|
||||||
* one byte message type.
|
* 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. */
|
/* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
|
||||||
total_attr_len = bgp_packet_attribute (NULL, peer, s,
|
total_attr_len = bgp_packet_attribute (NULL, peer, s,
|
||||||
adv->baa->attr, &vecarr,
|
adv->baa->attr, &vecarr,
|
||||||
NULL, afi, safi,
|
&rn->p, afi, safi,
|
||||||
from, NULL, NULL, 0, 0);
|
from, prd, tag, 0, 0);
|
||||||
|
|
||||||
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
|
space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
|
||||||
BGP_MAX_PACKET_SIZE_OVERFLOW;
|
BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||||
|
Loading…
Reference in New Issue
Block a user