summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r--bgpd/bgp_attr.c245
1 files changed, 134 insertions, 111 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index f34e6493..bc39f3b8 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -153,7 +153,6 @@ cluster_free (struct cluster_list *cluster)
XFREE (MTYPE_CLUSTER, cluster);
}
-#if 0
static struct cluster_list *
cluster_dup (struct cluster_list *cluster)
{
@@ -172,7 +171,6 @@ cluster_dup (struct cluster_list *cluster)
return new;
}
-#endif
static struct cluster_list *
cluster_intern (struct cluster_list *cluster)
@@ -322,6 +320,23 @@ transit_free (struct transit *transit)
XFREE (MTYPE_TRANSIT, transit);
}
+static struct transit *
+transit_dup (struct transit *transit)
+{
+ struct transit *new;
+
+ new = XCALLOC (MTYPE_TRANSIT, sizeof (struct transit));
+ new->length = transit->length;
+ if (new->length)
+ {
+ new->val = XMALLOC (MTYPE_TRANSIT_VAL, transit->length);
+ memcpy (new->val, transit->val, transit->length);
+ }
+ else
+ new->val = NULL;
+
+ return new;
+}
static void *
transit_hash_alloc (void *p)
@@ -458,6 +473,46 @@ bgp_attr_dup (struct attr *new, struct attr *orig)
}
}
+void
+bgp_attr_deep_dup (struct attr *new, struct attr *orig)
+{
+ if (orig->aspath)
+ new->aspath = aspath_dup(orig->aspath);
+
+ if (orig->community)
+ new->community = community_dup(orig->community);
+
+ if (orig->extra)
+ {
+ if (orig->extra->ecommunity)
+ new->extra->ecommunity = ecommunity_dup(orig->extra->ecommunity);
+ if (orig->extra->cluster)
+ new->extra->cluster = cluster_dup(orig->extra->cluster);
+ if (orig->extra->transit)
+ new->extra->transit = transit_dup(orig->extra->transit);
+ }
+}
+
+void
+bgp_attr_deep_free (struct attr *attr)
+{
+ if (attr->aspath)
+ aspath_free(attr->aspath);
+
+ if (attr->community)
+ community_free(attr->community);
+
+ if (attr->extra)
+ {
+ if (attr->extra->ecommunity)
+ ecommunity_free(&attr->extra->ecommunity);
+ if (attr->extra->cluster)
+ cluster_free(attr->extra->cluster);
+ if (attr->extra->transit)
+ transit_free(attr->extra->transit);
+ }
+}
+
unsigned long int
attr_count (void)
{
@@ -495,6 +550,7 @@ attrhash_key_make (void *p)
MIX(extra->weight);
MIX(extra->mp_nexthop_global_in.s_addr);
MIX(extra->originator_id.s_addr);
+ MIX(extra->tag);
}
if (attr->aspath)
@@ -540,6 +596,7 @@ attrhash_cmp (const void *p1, const void *p2)
&& ae1->aggregator_as == ae2->aggregator_as
&& ae1->aggregator_addr.s_addr == ae2->aggregator_addr.s_addr
&& ae1->weight == ae2->weight
+ && ae1->tag == ae2->tag
&& ae1->mp_nexthop_len == ae2->mp_nexthop_len
&& IPV6_ADDR_SAME (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global)
&& IPV6_ADDR_SAME (&ae1->mp_nexthop_local, &ae2->mp_nexthop_local)
@@ -691,6 +748,7 @@ bgp_attr_default_set (struct attr *attr, u_char origin)
attr->aspath = aspath_empty ();
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT;
+ attr->extra->tag = 0;
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
attr->extra->mp_nexthop_len = IPV6_MAX_BYTELEN;
@@ -717,10 +775,12 @@ bgp_attr_default_intern (u_char origin)
return new;
}
+/* Create the attributes for an aggregate */
struct attr *
bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
struct aspath *aspath,
- struct community *community, int as_set)
+ struct community *community, int as_set,
+ u_char atomic_aggregate)
{
struct attr attr;
struct attr *new;
@@ -753,7 +813,7 @@ bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
attre.weight = BGP_ATTR_DEFAULT_WEIGHT;
attre.mp_nexthop_len = IPV6_MAX_BYTELEN;
- if (! as_set)
+ if (! as_set || atomic_aggregate)
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
@@ -962,19 +1022,18 @@ bgp_attr_flags_diagnose (struct bgp_attr_parser_args *args,
CHECK_FLAG (real_flags, attr_flag_str[i].key)
)
{
- zlog (args->peer->log, LOG_ERR, "%s attribute must%s be flagged as \"%s\"",
- LOOKUP (attr_str, attr_code),
- CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not",
- attr_flag_str[i].str);
+ zlog_err ("%s attribute must%s be flagged as \"%s\"",
+ LOOKUP (attr_str, attr_code),
+ CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not",
+ attr_flag_str[i].str);
seen = 1;
}
if (!seen)
{
- zlog (args->peer->log, LOG_DEBUG,
- "Strange, %s called for attr %s, but no problem found with flags"
- " (real flags 0x%x, desired 0x%x)",
- __func__, LOOKUP (attr_str, attr_code),
- real_flags, desired_flags);
+ zlog_debug ("Strange, %s called for attr %s, but no problem found with flags"
+ " (real flags 0x%x, desired 0x%x)",
+ __func__, LOOKUP (attr_str, attr_code),
+ real_flags, desired_flags);
}
}
@@ -1007,7 +1066,6 @@ bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
u_int8_t mask = BGP_ATTR_FLAG_EXTLEN;
const u_int8_t flags = args->flags;
const u_int8_t attr_code = args->type;
- struct peer *const peer = args->peer;
/* there may be attributes we don't know about */
if (attr_code > attr_flags_values_max)
@@ -1021,9 +1079,8 @@ bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
if (!CHECK_FLAG (BGP_ATTR_FLAG_OPTIONAL, flags)
&& !CHECK_FLAG (BGP_ATTR_FLAG_TRANS, flags))
{
- zlog (peer->log, LOG_ERR,
- "%s well-known attributes must have transitive flag set (%x)",
- LOOKUP (attr_str, attr_code), flags);
+ zlog_err ("%s well-known attributes must have transitive flag set (%x)",
+ LOOKUP (attr_str, attr_code), flags);
return 1;
}
@@ -1034,19 +1091,17 @@ bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
{
if (!CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL))
{
- zlog (peer->log, LOG_ERR,
- "%s well-known attribute "
- "must NOT have the partial flag set (%x)",
- LOOKUP (attr_str, attr_code), flags);
+ zlog_err ("%s well-known attribute "
+ "must NOT have the partial flag set (%x)",
+ LOOKUP (attr_str, attr_code), flags);
return 1;
}
if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
&& !CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
{
- zlog (peer->log, LOG_ERR,
- "%s optional + transitive attribute "
- "must NOT have the partial flag set (%x)",
- LOOKUP (attr_str, attr_code), flags);
+ zlog_err ("%s optional + transitive attribute "
+ "must NOT have the partial flag set (%x)",
+ LOOKUP (attr_str, attr_code), flags);
return 1;
}
}
@@ -1081,8 +1136,7 @@ bgp_attr_origin (struct bgp_attr_parser_args *args)
value). */
if (length != 1)
{
- zlog (peer->log, LOG_ERR, "Origin attribute length is not one %d",
- length);
+ zlog_err ("Origin attribute length is not one %d", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
@@ -1098,8 +1152,7 @@ bgp_attr_origin (struct bgp_attr_parser_args *args)
&& (attr->origin != BGP_ORIGIN_EGP)
&& (attr->origin != BGP_ORIGIN_INCOMPLETE))
{
- zlog (peer->log, LOG_ERR, "Origin attribute value is invalid %d",
- attr->origin);
+ zlog_err ("Origin attribute value is invalid %d", attr->origin);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
args->total);
@@ -1130,9 +1183,7 @@ bgp_attr_aspath (struct bgp_attr_parser_args *args)
/* In case of IBGP, length will be zero. */
if (! attr->aspath)
{
- zlog (peer->log, LOG_ERR,
- "Malformed AS path from %s, length is %d",
- peer->host, length);
+ zlog_err ("Malformed AS path from %s, length is %d", peer->host, length);
return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_MAL_AS_PATH, 0);
}
@@ -1159,7 +1210,7 @@ bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
if ((peer->sort == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
(peer->sort == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
{
- zlog (peer->log, LOG_ERR, "Malformed AS path from %s", peer->host);
+ zlog_err ("Malformed AS path from %s", peer->host);
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_AS_PATH);
return BGP_ATTR_PARSE_ERROR;
@@ -1171,8 +1222,7 @@ bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
if (peer->sort == BGP_PEER_EBGP
&& ! aspath_firstas_check (attr->aspath, peer->as))
{
- zlog (peer->log, LOG_ERR,
- "%s incorrect first AS (must be %u)", peer->host, peer->as);
+ zlog_err ("%s incorrect first AS (must be %u)", peer->host, peer->as);
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_AS_PATH);
return BGP_ATTR_PARSE_ERROR;
@@ -1206,9 +1256,7 @@ bgp_attr_as4_path (struct bgp_attr_parser_args *args, struct aspath **as4_path)
/* In case of IBGP, length will be zero. */
if (!*as4_path)
{
- zlog (peer->log, LOG_ERR,
- "Malformed AS4 path from %s, length is %d",
- peer->host, length);
+ zlog_err ("Malformed AS4 path from %s, length is %d", peer->host, length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_MAL_AS_PATH,
0);
@@ -1234,8 +1282,7 @@ bgp_attr_nexthop (struct bgp_attr_parser_args *args)
/* Check nexthop attribute length. */
if (length != 4)
{
- zlog (peer->log, LOG_ERR, "Nexthop attribute length isn't four [%d]",
- length);
+ zlog_err ("Nexthop attribute length isn't four [%d]", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
@@ -1253,7 +1300,7 @@ bgp_attr_nexthop (struct bgp_attr_parser_args *args)
{
char buf[INET_ADDRSTRLEN];
inet_ntop (AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
- zlog (peer->log, LOG_ERR, "Martian nexthop %s", buf);
+ zlog_err ("Martian nexthop %s", buf);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
args->total);
@@ -1276,8 +1323,7 @@ bgp_attr_med (struct bgp_attr_parser_args *args)
/* Length check. */
if (length != 4)
{
- zlog (peer->log, LOG_ERR,
- "MED attribute length isn't four [%d]", length);
+ zlog_err ("MED attribute length isn't four [%d]", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
@@ -1302,8 +1348,7 @@ bgp_attr_local_pref (struct bgp_attr_parser_args *args)
/* Length check. */
if (length != 4)
{
- zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute length isn't 4 [%u]",
- length);
+ zlog_err ("LOCAL_PREF attribute length isn't 4 [%u]", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
@@ -1330,15 +1375,13 @@ bgp_attr_local_pref (struct bgp_attr_parser_args *args)
static int
bgp_attr_atomic (struct bgp_attr_parser_args *args)
{
- struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
const bgp_size_t length = args->length;
/* Length check. */
if (length != 0)
{
- zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
- length);
+ zlog_err ("ATOMIC_AGGREGATE attribute length isn't 0 [%u]", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
@@ -1367,8 +1410,7 @@ bgp_attr_aggregator (struct bgp_attr_parser_args *args)
if (length != wantedlen)
{
- zlog (peer->log, LOG_ERR, "AGGREGATOR attribute length isn't %u [%u]",
- wantedlen, length);
+ zlog_err ("AGGREGATOR attribute length isn't %u [%u]", wantedlen, length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
@@ -1398,8 +1440,7 @@ bgp_attr_as4_aggregator (struct bgp_attr_parser_args *args,
if (length != 8)
{
- zlog (peer->log, LOG_ERR, "New Aggregator length is not 8 [%d]",
- length);
+ zlog_err ("New Aggregator length is not 8 [%d]", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
0);
@@ -1562,7 +1603,7 @@ bgp_attr_originator_id (struct bgp_attr_parser_args *args)
/* Length check. */
if (length != 4)
{
- zlog (peer->log, LOG_ERR, "Bad originator ID length %d", length);
+ zlog_err ("Bad originator ID length %d", length);
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
@@ -1588,7 +1629,7 @@ bgp_attr_cluster_list (struct bgp_attr_parser_args *args)
/* Check length. */
if (length % 4)
{
- zlog (peer->log, LOG_ERR, "Bad cluster list length %d", length);
+ zlog_err ("Bad cluster list length %d", length);
return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
@@ -1698,8 +1739,8 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
char buf1[INET6_ADDRSTRLEN];
char buf2[INET6_ADDRSTRLEN];
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog_debug ("%s got two nexthop %s %s but second one is not a link-local nexthop", peer->host,
+ if (bgp_debug_update(peer, NULL, 1))
+ zlog_debug ("%s sent two nexthops %s %s but second one is not a link-local nexthop", peer->host,
inet_ntop (AF_INET6, &attre->mp_nexthop_global,
buf1, INET6_ADDRSTRLEN),
inet_ntop (AF_INET6, &attre->mp_nexthop_local,
@@ -1736,7 +1777,7 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
__func__, peer->host);
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
}
-
+
mp_update->afi = afi;
mp_update->safi = safi;
mp_update->nlri = stream_pnt (s);
@@ -1837,8 +1878,7 @@ bgp_attr_encap(
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
{
- zlog (peer->log, LOG_ERR,
- "Tunnel Encap attribute flag isn't optional and transitive %d", flag);
+ zlog_err ("Tunnel Encap attribute flag isn't optional and transitive %d", flag);
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
@@ -1851,8 +1891,7 @@ bgp_attr_encap(
uint16_t tlv_length;
if (length < 4) {
- zlog (peer->log, LOG_ERR,
- "Tunnel Encap attribute not long enough to contain outer T,L");
+ zlog_err ("Tunnel Encap attribute not long enough to contain outer T,L");
bgp_notify_send_with_data(peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
@@ -1864,7 +1903,7 @@ bgp_attr_encap(
length -= 4;
if (tlv_length != length) {
- zlog (peer->log, LOG_ERR, "%s: tlv_length(%d) != length(%d)",
+ zlog_err ("%s: tlv_length(%d) != length(%d)",
__func__, tlv_length, length);
}
}
@@ -1881,8 +1920,7 @@ bgp_attr_encap(
}
if (sublength > length) {
- zlog (peer->log, LOG_ERR,
- "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
+ zlog_err ("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
sublength, length);
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
@@ -1923,8 +1961,7 @@ bgp_attr_encap(
if (length) {
/* spurious leftover data */
- zlog (peer->log, LOG_ERR,
- "Tunnel Encap attribute length is bad: %d leftover octets", length);
+ zlog_err ("Tunnel Encap attribute length is bad: %d leftover octets", length);
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
@@ -1949,15 +1986,10 @@ bgp_attr_unknown (struct bgp_attr_parser_args *args)
const u_char flag = args->flags;
const bgp_size_t length = args->length;
-
- if (BGP_DEBUG (normal, NORMAL))
- zlog_debug ("%s Unknown attribute is received (type %d, length %d)",
- peer->host, type, length);
+ if (bgp_debug_update(peer, NULL, 1))
+ zlog_debug ("%s Unknown attribute is received (type %d, length %d)",
+ peer->host, type, length);
- if (BGP_DEBUG (events, EVENTS))
- zlog (peer->log, LOG_DEBUG,
- "Unknown attribute type %d length %d is received", type, length);
-
/* Forward read pointer of input stream. */
stream_forward_getp (peer->ibuf, length);
@@ -2039,9 +2071,7 @@ bgp_attr_check (struct peer *peer, struct attr *attr)
if (type)
{
- zlog (peer->log, LOG_WARNING,
- "%s Missing well-known attribute %d / %s",
- peer->host, type, LOOKUP (attr_str, type));
+ zlog_warn ("%s Missing well-known attribute %d.", peer->host, type);
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MISS_ATTR,
@@ -2083,10 +2113,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
if (endp - BGP_INPUT_PNT (peer) < BGP_ATTR_MIN_LEN)
{
/* XXX warning: long int format, int arg (arg 5) */
- zlog (peer->log, LOG_WARNING,
- "%s: error BGP attribute length %lu is smaller than min len",
- peer->host,
- (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
+ zlog_warn ("%s: error BGP attribute length %lu is smaller than min len",
+ peer->host,
+ (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
@@ -2106,10 +2135,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN)
&& ((endp - startp) < (BGP_ATTR_MIN_LEN + 1)))
{
- zlog (peer->log, LOG_WARNING,
- "%s: Extended length set, but just %lu bytes of attr header",
- peer->host,
- (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
+ zlog_warn ("%s: Extended length set, but just %lu bytes of attr header",
+ peer->host,
+ (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
@@ -2129,9 +2157,8 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
if (CHECK_BITMAP (seen, type))
{
- zlog (peer->log, LOG_WARNING,
- "%s: error BGP attribute type %d appears twice in a message",
- peer->host, type);
+ zlog_warn ("%s: error BGP attribute type %d appears twice in a message",
+ peer->host, type);
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
@@ -2149,11 +2176,11 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
if (attr_endp > endp)
{
- zlog (peer->log, LOG_WARNING,
- "%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p", peer->host, type, length, size, attr_endp, endp);
- bgp_notify_send (peer,
- BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
+ zlog_warn ("%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p", peer->host, type, length, size, attr_endp, endp);
+ bgp_notify_send_with_data (peer,
+ BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ startp, attr_endp - startp);
return BGP_ATTR_PARSE_ERROR;
}
@@ -2252,10 +2279,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
/* If hard error occured immediately return to the caller. */
if (ret == BGP_ATTR_PARSE_ERROR)
{
- zlog (peer->log, LOG_WARNING,
- "%s: Attribute %s, parse error",
- peer->host,
- LOOKUP (attr_str, type));
+ zlog_warn ("%s: Attribute %s, parse error",
+ peer->host,
+ LOOKUP (attr_str, type));
if (as4_path)
aspath_unintern (&as4_path);
return ret;
@@ -2263,10 +2289,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
if (ret == BGP_ATTR_PARSE_WITHDRAW)
{
- zlog (peer->log, LOG_WARNING,
- "%s: Attribute %s, parse error - treating as withdrawal",
- peer->host,
- LOOKUP (attr_str, type));
+ zlog_warn ("%s: Attribute %s, parse error - treating as withdrawal",
+ peer->host,
+ LOOKUP (attr_str, type));
if (as4_path)
aspath_unintern (&as4_path);
return ret;
@@ -2275,9 +2300,8 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
/* Check the fetched length. */
if (BGP_INPUT_PNT (peer) != attr_endp)
{
- zlog (peer->log, LOG_WARNING,
- "%s: BGP attribute %s, fetch error",
- peer->host, LOOKUP (attr_str, type));
+ zlog_warn ("%s: BGP attribute %s, fetch error",
+ peer->host, LOOKUP (attr_str, type));
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
@@ -2289,9 +2313,8 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
/* Check final read pointer is same as end pointer. */
if (BGP_INPUT_PNT (peer) != endp)
{
- zlog (peer->log, LOG_WARNING,
- "%s: BGP attribute %s, length mismatch",
- peer->host, LOOKUP (attr_str, type));
+ zlog_warn ("%s: BGP attribute %s, length mismatch",
+ peer->host, LOOKUP (attr_str, type));
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
@@ -2547,8 +2570,7 @@ bgp_packet_mpattr_tea(
}
if (attrlenfield > 0xffff) {
- zlog (peer->log, LOG_ERR,
- "%s attribute is too long (length=%d), can't send it",
+ zlog_err ("%s attribute is too long (length=%d), can't send it",
attrname,
attrlenfield);
return;
@@ -2705,12 +2727,13 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
}
/* MED attribute. */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC) ||
+ bgp->maxmed_active)
{
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
stream_putc (s, 4);
- stream_putl (s, attr->med);
+ stream_putl (s, (bgp->maxmed_active ? bgp->maxmed_value : attr->med));
}
/* Local preference. */