X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=bgpd%2Fbgp_attr.c;h=6784e632062c389dac1429130262c108b1f695a3;hb=2af482767c9197646e21dbb605ab12e690b8a266;hp=2f246e61d85cdd9be028dbe07b0aee253764eead;hpb=80e39114b502f683638c58de94e4125fc85a3478;p=mirror_frr.git diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 2f246e61d..6784e6320 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -847,7 +847,7 @@ struct attr *bgp_attr_intern(struct attr *attr) struct lcommunity *lcomm = NULL; struct community *comm = NULL; - /* Intern referenced strucutre. */ + /* Intern referenced structure. */ if (attr->aspath) { if (!attr->aspath->refcnt) attr->aspath = aspath_intern(attr->aspath); @@ -951,7 +951,8 @@ struct attr *bgp_attr_intern(struct attr *attr) } /* Make network statement's attribute. */ -struct attr *bgp_attr_default_set(struct attr *attr, uint8_t origin) +struct attr *bgp_attr_default_set(struct attr *attr, struct bgp *bgp, + uint8_t origin) { memset(attr, 0, sizeof(struct attr)); @@ -965,6 +966,7 @@ struct attr *bgp_attr_default_set(struct attr *attr, uint8_t origin) attr->label = MPLS_INVALID_LABEL; attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); attr->mp_nexthop_len = IPV6_MAX_BYTELEN; + attr->local_pref = bgp->default_local_pref; return attr; } @@ -980,12 +982,16 @@ struct attr *bgp_attr_aggregate_intern( struct attr *new; int ret; - memset(&attr, 0, sizeof(struct attr)); + memset(&attr, 0, sizeof(attr)); /* Origin attribute. */ attr.origin = origin; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN); + /* MED */ + attr.med = 0; + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); + /* AS path attribute. */ if (aspath) attr.aspath = aspath_intern(aspath); @@ -1008,18 +1014,13 @@ struct attr *bgp_attr_aggregate_intern( } bgp_attr_set_community(&attr, community); - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES); } - if (ecommunity) { + if (ecommunity) bgp_attr_set_ecommunity(&attr, ecommunity); - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); - } - if (lcommunity) { + if (lcommunity) bgp_attr_set_lcommunity(&attr, lcommunity); - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES); - } if (bgp_in_graceful_shutdown(bgp)) bgp_attr_add_gshut_community(&attr); @@ -1044,7 +1045,7 @@ struct attr *bgp_attr_aggregate_intern( struct attr attr_tmp = attr; struct bgp_path_info rmap_path; - memset(&rmap_path, 0, sizeof(struct bgp_path_info)); + memset(&rmap_path, 0, sizeof(rmap_path)); rmap_path.peer = bgp->peer_self; rmap_path.attr = &attr_tmp; @@ -1096,22 +1097,18 @@ void bgp_attr_unintern_sub(struct attr *attr) comm = bgp_attr_get_community(attr); community_unintern(&comm); - UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)); bgp_attr_set_community(attr, NULL); ecomm = bgp_attr_get_ecommunity(attr); ecommunity_unintern(&ecomm); - UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)); bgp_attr_set_ecommunity(attr, NULL); ipv6_ecomm = bgp_attr_get_ipv6_ecommunity(attr); ecommunity_unintern(&ipv6_ecomm); - UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES)); bgp_attr_set_ipv6_ecommunity(attr, NULL); lcomm = bgp_attr_get_lcommunity(attr); lcommunity_unintern(&lcomm); - UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)); bgp_attr_set_lcommunity(attr, NULL); cluster = bgp_attr_get_cluster(attr); @@ -1243,7 +1240,7 @@ void bgp_attr_flush(struct attr *attr) * are partial/optional and hence where the error likely was not * introduced by the sending neighbour. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, bgp_size_t length) { @@ -1450,7 +1447,8 @@ static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) } /* Get origin attribute of the update message. */ -static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args) +static enum bgp_attr_parse_ret +bgp_attr_origin(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; struct attr *const attr = args->attr; @@ -1520,8 +1518,8 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args) return BGP_ATTR_PARSE_PROCEED; } -static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, - struct attr *const attr) +static enum bgp_attr_parse_ret bgp_attr_aspath_check(struct peer *const peer, + struct attr *const attr) { /* These checks were part of bgp_attr_aspath, but with * as4 we should to check aspath things when @@ -1603,15 +1601,15 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args, /* * Check that the nexthop attribute is valid. */ -bgp_attr_parse_ret_t -bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr) +enum bgp_attr_parse_ret bgp_attr_nexthop_valid(struct peer *peer, + struct attr *attr) { in_addr_t nexthop_h; nexthop_h = ntohl(attr->nexthop.s_addr); - if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h) - || IPV4_CLASS_DE(nexthop_h)) - && !BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) { + if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h) || + !ipv4_unicast_valid(&attr->nexthop)) && + !BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) { uint8_t data[7]; /* type(2) + length(1) + nhop(4) */ char buf[INET_ADDRSTRLEN]; @@ -1633,7 +1631,8 @@ bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr) } /* Nexthop attribute. */ -static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) +static enum bgp_attr_parse_ret +bgp_attr_nexthop(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; struct attr *const attr = args->attr; @@ -1655,7 +1654,7 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) } /* MED atrribute. */ -static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args) +static enum bgp_attr_parse_ret bgp_attr_med(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; struct attr *const attr = args->attr; @@ -1678,7 +1677,7 @@ static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args) } /* Local preference attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_local_pref(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -1790,7 +1789,7 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args) } /* New Aggregator attribute */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args, as_t *as4_aggregator_as, struct in_addr *as4_aggregator_addr) @@ -1834,7 +1833,7 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args, /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr, struct aspath *as4_path, as_t as4_aggregator, struct in_addr *as4_aggregator_addr) @@ -1936,7 +1935,7 @@ bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr, } /* Community attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_community(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -1963,13 +1962,11 @@ bgp_attr_community(struct bgp_attr_parser_args *args) return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES); - return BGP_ATTR_PARSE_PROCEED; } /* Originator ID attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_originator_id(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -1997,7 +1994,7 @@ bgp_attr_originator_id(struct bgp_attr_parser_args *args) } /* Cluster list attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_cluster_list(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -2268,7 +2265,7 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args, } /* Large Community attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_large_community(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -2294,13 +2291,11 @@ bgp_attr_large_community(struct bgp_attr_parser_args *args) return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES); - return BGP_ATTR_PARSE_PROCEED; } /* Extended Community attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_ext_communities(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -2332,8 +2327,6 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); - /* Extract DF election preference and mobility sequence number */ attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg); @@ -2376,7 +2369,7 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) } /* IPv6 Extended Community attribute. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -2403,8 +2396,6 @@ bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args) return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES); - return BGP_ATTR_PARSE_PROCEED; } @@ -2541,7 +2532,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ /* SRv6 Service Data Sub-Sub-TLV attribute * draft-ietf-bess-srv6-services-07 */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_srv6_service_data(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -2622,7 +2613,7 @@ bgp_attr_srv6_service_data(struct bgp_attr_parser_args *args) /* SRv6 Service Sub-TLV attribute * draft-ietf-bess-srv6-services-07 */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_srv6_service(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -2631,7 +2622,7 @@ bgp_attr_srv6_service(struct bgp_attr_parser_args *args) uint8_t type, sid_flags; uint16_t length, endpoint_behavior; size_t headersz = sizeof(type) + sizeof(length); - bgp_attr_parse_ret_t err; + enum bgp_attr_parse_ret err; char buf[BUFSIZ]; if (STREAM_READABLE(peer->curr) < headersz) { @@ -2717,8 +2708,9 @@ bgp_attr_srv6_service(struct bgp_attr_parser_args *args) * Read an individual SID value returning how much data we have read * Returns 0 if there was an error that needs to be passed up the stack */ -static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length, - struct bgp_attr_parser_args *args) +static enum bgp_attr_parse_ret +bgp_attr_psid_sub(uint8_t type, uint16_t length, + struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; struct attr *const attr = args->attr; @@ -2925,11 +2917,11 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length, /* Prefix SID attribute * draft-ietf-idr-bgp-prefix-sid-05 */ -bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args) +enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; struct attr *const attr = args->attr; - bgp_attr_parse_ret_t ret; + enum bgp_attr_parse_ret ret; attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID); @@ -2988,7 +2980,7 @@ bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args) /* PMSI tunnel attribute (RFC 6514) * Basic validation checks done here. */ -static bgp_attr_parse_ret_t +static enum bgp_attr_parse_ret bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args) { struct peer *const peer = args->peer; @@ -3036,7 +3028,8 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args) } /* BGP unknown attribute treatment. */ -static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args) +static enum bgp_attr_parse_ret +bgp_attr_unknown(struct bgp_attr_parser_args *args) { bgp_size_t total = args->total; struct transit *transit; @@ -3141,11 +3134,12 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr) /* Read attribute of update packet. This function is called from bgp_update_receive() in bgp_packet.c. */ -bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, - bgp_size_t size, struct bgp_nlri *mp_update, - struct bgp_nlri *mp_withdraw) +enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, + bgp_size_t size, + struct bgp_nlri *mp_update, + struct bgp_nlri *mp_withdraw) { - bgp_attr_parse_ret_t ret; + enum bgp_attr_parse_ret ret; uint8_t flag = 0; uint8_t type = 0; bgp_size_t length; @@ -3604,8 +3598,8 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, struct attr *attr) { size_t sizep; - iana_afi_t pkt_afi; - iana_safi_t pkt_safi; + iana_afi_t pkt_afi = IANA_AFI_IPV4; + iana_safi_t pkt_safi = IANA_SAFI_UNICAST; afi_t nh_afi; /* Set extended bit always to encode the attribute length as 2 bytes */ @@ -4185,9 +4179,14 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY) && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr); - - if (peer->sort == BGP_PEER_IBGP - || peer->sort == BGP_PEER_CONFED) { + bool transparent = CHECK_FLAG(peer->af_flags[afi][safi], + PEER_FLAG_RSERVER_CLIENT) && + from && + CHECK_FLAG(from->af_flags[afi][safi], + PEER_FLAG_RSERVER_CLIENT); + + if (peer->sort == BGP_PEER_IBGP || + peer->sort == BGP_PEER_CONFED || transparent) { if (ecomm->size * 8 > 255) { stream_putc(s, BGP_ATTR_FLAG_OPTIONAL @@ -4407,8 +4406,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi) { unsigned long attrlen_pnt; - iana_afi_t pkt_afi; - iana_safi_t pkt_safi; + iana_afi_t pkt_afi = IANA_AFI_IPV4; + iana_safi_t pkt_safi = IANA_SAFI_UNICAST; /* Set extended bit always to encode the attribute length as 2 bytes */ stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN); @@ -4433,7 +4432,7 @@ void bgp_packet_mpunreach_prefix(struct stream *s, const struct prefix *p, bool addpath_capable, uint32_t addpath_tx_id, struct attr *attr) { - uint8_t wlabel[3] = {0x80, 0x00, 0x00}; + uint8_t wlabel[4] = {0x80, 0x00, 0x00}; if (safi == SAFI_LABELED_UNICAST) { label = (mpls_label_t *)wlabel;