projects
/
quagga-debian.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
New upstream version 1.2.3
[quagga-debian.git]
/
bgpd
/
bgp_attr.c
diff --git
a/bgpd/bgp_attr.c
b/bgpd/bgp_attr.c
index a79a03cc6323195d677585ee5e3c9a67278c032f..0c2806b5299fdf8a565f938119c9625e9b8483b2 100644
(file)
--- a/
bgpd/bgp_attr.c
+++ b/
bgpd/bgp_attr.c
@@
-199,15
+199,17
@@
cluster_intern (struct cluster_list *cluster)
}
void
}
void
-cluster_unintern (struct cluster_list *cluster)
+cluster_unintern (struct cluster_list *
*
cluster)
{
{
- if (cluster->refcnt)
- cluster->refcnt--;
+ struct cluster_list *c = *cluster;
+ if (c->refcnt)
+ c->refcnt--;
- if (c
luster
->refcnt == 0)
+ if (c->refcnt == 0)
{
{
- hash_release (cluster_hash, cluster);
- cluster_free (cluster);
+ hash_release (cluster_hash, c);
+ cluster_free (c);
+ *cluster = NULL;
}
}
}
}
@@
-357,15
+359,18
@@
transit_intern (struct transit *transit)
}
void
}
void
-transit_unintern (struct transit *transit)
+transit_unintern (struct transit *
*
transit)
{
{
- if (transit->refcnt)
- transit->refcnt--;
+ struct transit *t = *transit;
+
+ if (t->refcnt)
+ t->refcnt--;
- if (t
ransit
->refcnt == 0)
+ if (t->refcnt == 0)
{
{
- hash_release (transit_hash, transit);
- transit_free (transit);
+ hash_release (transit_hash, t);
+ transit_free (t);
+ *transit = NULL;
}
}
}
}
@@
-820,11
+825,11
@@
bgp_attr_unintern_sub (struct attr *attr)
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
if (attr->extra->cluster)
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
if (attr->extra->cluster)
- cluster_unintern (attr->extra->cluster);
+ cluster_unintern (
&
attr->extra->cluster);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
if (attr->extra->transit)
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
if (attr->extra->transit)
- transit_unintern (attr->extra->transit);
+ transit_unintern (
&
attr->extra->transit);
}
}
}
}
@@
-897,7
+902,7
@@
bgp_attr_flush (struct attr *attr)
}
}
}
}
-/* Implement
draft-scudder-idr-optional-transitive
behaviour and
+/* Implement
some draft-ietf-idr-error-handling
behaviour and
* avoid resetting sessions for malformed attributes which are
* are partial/optional and hence where the error likely was not
* introduced by the sending neighbour.
* avoid resetting sessions for malformed attributes which are
* are partial/optional and hence where the error likely was not
* introduced by the sending neighbour.
@@
-914,6
+919,11
@@
bgp_attr_malformed (struct bgp_attr_parser_args *args, u_char subcode,
*/
u_char *notify_datap = (length > 0 ? args->startp : NULL);
*/
u_char *notify_datap = (length > 0 ? args->startp : NULL);
+ /* The malformed attribute shouldn't be passed on, should
+ * we decide to proceed with parsing the UPDATE
+ */
+ UNSET_FLAG (args->attr->flag, ATTR_FLAG_BIT (args->type));
+
/* Only relax error handling for eBGP peers */
if (peer->sort != BGP_PEER_EBGP)
{
/* Only relax error handling for eBGP peers */
if (peer->sort != BGP_PEER_EBGP)
{
@@
-970,7
+980,9
@@
bgp_attr_malformed (struct bgp_attr_parser_args *args, u_char subcode,
return BGP_ATTR_PARSE_WITHDRAW;
/* default to reset */
return BGP_ATTR_PARSE_WITHDRAW;
/* default to reset */
- return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
+ bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
+ notify_datap, length);
+ return BGP_ATTR_PARSE_ERROR;
}
/* Find out what is wrong with the path attribute flag bits and log the error.
}
/* Find out what is wrong with the path attribute flag bits and log the error.
@@
-2140,6
+2152,8
@@
bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
memset (seen, 0, BGP_ATTR_BITMAP_SIZE);
/* End pointer of BGP attribute. */
memset (seen, 0, BGP_ATTR_BITMAP_SIZE);
/* End pointer of BGP attribute. */
+ assert (size <= stream_get_size (BGP_INPUT (peer)));
+ assert (size <= stream_get_endp (BGP_INPUT (peer)));
endp = BGP_INPUT_PNT (peer) + size;
/* Get attributes to the end of attribute length. */
endp = BGP_INPUT_PNT (peer) + size;
/* Get attributes to the end of attribute length. */
@@
-2221,7
+2235,7
@@
bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- startp,
attr_
endp - startp);
+ startp, endp - startp);
return BGP_ATTR_PARSE_ERROR;
}
return BGP_ATTR_PARSE_ERROR;
}
@@
-2320,7
+2334,7
@@
bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
ret = BGP_ATTR_PARSE_ERROR;
}
ret = BGP_ATTR_PARSE_ERROR;
}
- /* If hard error occured immediately return to the caller. */
+ /* If hard error occur
r
ed immediately return to the caller. */
if (ret == BGP_ATTR_PARSE_ERROR)
{
zlog (peer->log, LOG_WARNING,
if (ret == BGP_ATTR_PARSE_ERROR)
{
zlog (peer->log, LOG_WARNING,