summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_packet.c
diff options
context:
space:
mode:
authorChris Hall <chris.hall@highwayman.com>2012-03-23 12:15:00 +0000
committerChris Hall <chris.hall@highwayman.com>2012-03-23 12:15:00 +0000
commit4526b03b4c1ac32588cd8f9a3ea71bafe72db9ef (patch)
tree48c05781305667727e1dcd2207df6c25976bb488 /bgpd/bgp_packet.c
parent97f375b3e02e0f4ec18f68fbe36fc5ae16693d26 (diff)
parentaee567450eaf32877d00f47c4cc5d05c5fb85a51 (diff)
downloadquagga-ex23b.tar.bz2
quagga-ex23b.tar.xz
Merge branch 'master' into euro_ix_bex23b
v0.99.20ex23b -- Quagga 'master' as at 23-Mar-2012 Conflicts: bgpd/bgp_attr.c bgpd/bgp_attr.h Difference between 'master' and 0.99.20.1 is in these files. Handling of attributes has been worked over again to common up checks of the flags, and to use a common parsing structure, which reduces the clutter of parameters for the individual attribute parsing functions. bgpd/bgp_open.c bgpd/bgp_packet.c lib/thread.c ospfd/ospf_packet.c These were artifacts, caused by common patches in master and 0.99.20.1 -- and some twitchy-ness about whitespace !
Diffstat (limited to 'bgpd/bgp_packet.c')
-rw-r--r--bgpd/bgp_packet.c224
1 files changed, 108 insertions, 116 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index fad72c36..7a709ecd 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -671,16 +671,10 @@ int
bgp_update_receive (struct peer *peer, bgp_size_t size)
{
int ret;
- struct stream *s;
- struct attr attr;
bgp_size_t attribute_len;
- struct bgp_nlri update;
- struct bgp_nlri withdraw;
- struct bgp_nlri mp_update;
- struct bgp_nlri mp_withdraw;
- bool mp_eor ;
char attrstr[BUFSIZ] = "";
bgp_attr_parse_ret_t ap_ret ;
+ bgp_attr_parser_args_t args[1] ;
/* Status must be Established. */
if (peer->state != bgp_peer_pEstablished)
@@ -692,18 +686,15 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
}
/* Set initial values. */
- memset (&attr, 0, sizeof (struct attr));
- memset (&update, 0, sizeof (struct bgp_nlri));
- memset (&withdraw, 0, sizeof (struct bgp_nlri));
- memset (&mp_update, 0, sizeof (struct bgp_nlri));
- memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
+ memset (args, 0, sizeof (args));
- s = peer->ibuf;
+ args->peer = peer ;
+ args->s = peer->ibuf ;
/* Unfeasible Route Length.
*/
- withdraw.length = stream_getw (s);
- if (stream_has_overrun(s))
+ args->withdraw.length = stream_getw (args->s);
+ if (stream_has_overrun(args->s))
{
zlog_err ("%s [Error] Update packet error"
" (packet length is short for unfeasible length)",
@@ -715,43 +706,43 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
/* Unfeasible Route packet format check.
*/
- if (withdraw.length > 0)
+ if (args->withdraw.length > 0)
{
ulen endp ;
- endp = stream_push_endp(s, withdraw.length) ;
- if (stream_has_overrun(s))
+ endp = stream_push_endp(args->s, args->withdraw.length) ;
+ if (stream_has_overrun(args->s))
{
zlog_err ("%s [Error] Update packet error"
" (packet unfeasible length overflow %d)",
- peer->host, withdraw.length);
+ peer->host, args->withdraw.length);
bgp_peer_down_error (peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_ATTR);
return -1;
}
- ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_get_pnt (s),
- withdraw.length);
+ ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_get_pnt (args->s),
+ args->withdraw.length);
if (ret < 0)
{
- zlog_info ("%s withdraw NLRI doesn't pass sanity check", peer->host) ;
+ zlog_info ("%s withdraw NLRI fails sanity check", peer->host) ;
return -1 ;
} ;
if (BGP_DEBUG (packet, PACKET_RECV))
zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
- withdraw.afi = AFI_IP;
- withdraw.safi = SAFI_UNICAST;
- withdraw.nlri = stream_get_pnt (s);
+ args->withdraw.afi = AFI_IP;
+ args->withdraw.safi = SAFI_UNICAST;
+ args->withdraw.nlri = stream_get_pnt (args->s);
- stream_pop_endp(s, endp) ; /* steps getp to given endp */
+ stream_pop_endp(args->s, endp) ; /* steps getp to given endp */
}
/* Fetch attribute total length.
*/
- attribute_len = stream_getw (s);
- if (stream_has_overrun(s))
+ attribute_len = stream_getw (args->s);
+ if (stream_has_overrun(args->s))
{
zlog_warn ("%s [Error] Packet Error"
" (update packet is short for attribute length)",
@@ -773,7 +764,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
/* This define morphs the update case into a withdraw when lower levels
* have signalled an error condition where this is best.
*/
-#define NLRI_ATTR_ARG (ap_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
+#define NLRI_ATTR_ARG (ap_ret != BGP_ATTR_PARSE_WITHDRAW ? &args->attr : NULL)
/* Parse attribute when it exists. */
if (attribute_len)
@@ -784,11 +775,11 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
* Set the s->endp to the end of the attributes, check that is within
* the current endp, and save the current endp.
*/
- endp = stream_push_endp(s, attribute_len) ;
- if (stream_has_overrun(s))
+ endp = stream_push_endp(args->s, attribute_len) ;
+ if (stream_has_overrun(args->s))
{
zlog_warn ("%s [Error] Packet Error"
- " (update packet attribute length overflow %d)",
+ " (update packet attribute length overflow %u)",
peer->host, attribute_len);
bgp_peer_down_error (peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_ATTR);
@@ -797,13 +788,13 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
/* Do the real work of parsing the attributes getp..endp.
*/
- ap_ret = bgp_attr_parse (peer, &attr, &mp_update, &mp_withdraw, &mp_eor);
+ ap_ret = bgp_attr_parse (args);
/* Restore the endp, checking that either the getp is at the end of the
* attributes or we have a serious error and no longer care about the
* stream pointers.
*/
- if (!stream_pop_endp(s, endp) && (ap_ret != BGP_ATTR_PARSE_ERROR))
+ if (!stream_pop_endp(args->s, endp) && (ap_ret != BGP_ATTR_PARSE_ERROR))
{
/* This is actually an internal error -- have somehow got out of
* step, without the check inside the loop spotting it !
@@ -860,7 +851,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
break ;
} ;
- if (bgp_dump_attr (peer, &attr, attrstr, BUFSIZ))
+ if (bgp_dump_attr (peer, &args->attr, attrstr, BUFSIZ))
zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
peer->host, attrstr);
@@ -874,24 +865,24 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
/* Network Layer Reachability Information.
*/
- update.length = stream_get_read_left(s);
+ args->update.length = stream_get_read_left(args->s);
- if (update.length)
+ if (args->update.length != 0)
{
/* Set NLRI portion to structure. */
- update.afi = AFI_IP;
- update.safi = SAFI_UNICAST;
- update.nlri = stream_get_pnt (s);
+ args->update.afi = AFI_IP;
+ args->update.safi = SAFI_UNICAST;
+ args->update.nlri = stream_get_pnt (args->s);
- ret = bgp_nlri_sanity_check (peer, update.afi, update.nlri,
- update.length) ;
+ ret = bgp_nlri_sanity_check (peer, args->update.afi, args->update.nlri,
+ args->update.length) ;
if (ret < 0)
{
- zlog_info ("%s update NLRI doesn't pass sanity check", peer->host) ;
+ zlog_info ("%s update NLRI fails sanity check", peer->host) ;
return -1 ;
} ;
- stream_forward_getp (s, update.length);
+ stream_forward_getp (args->s, args->update.length);
} ;
/* Now we check for the "mandatory" attributes -- if we have one, other or
@@ -900,9 +891,10 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
* Note that mp_update.length is a bit pointless, but we tolerate and ignore
* the attribute state.
*/
- if ((update.length != 0) || (mp_update.length != 0))
+ if ((args->update.length != 0) || (args->mp_update.length != 0))
{
- ret = bgp_attr_check (peer, &attr, update.length != 0 /* with NEXT_HOP */);
+ ret = bgp_attr_check (peer, &args->attr,
+ args->update.length != 0 /* with NEXT_HOP */);
if (ret < 0)
{
ret = -1 ;
@@ -920,34 +912,34 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
* Rule is that the MP_UNREACH_NLRI should be the *only* thing in the UPDATE
* message.
*/
- if (mp_eor)
+ if (args->mp_eor)
{
- if ((withdraw.length != 0) || (update.length != 0))
- mp_eor = false ;
+ if ((args->withdraw.length != 0) || (args->update.length != 0))
+ args->mp_eor = false ;
} ;
/* NLRI is processed only when the peer is configured specific
Address Family and Subsequent Address Family. */
if (peer->afc[AFI_IP][SAFI_UNICAST])
{
- if (withdraw.length)
- bgp_nlri_parse (peer, NULL, &withdraw);
+ if (args->withdraw.length)
+ bgp_nlri_parse (peer, NULL, &args->withdraw);
- if (update.length)
- bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
+ if (args->update.length)
+ bgp_nlri_parse (peer, NLRI_ATTR_ARG, &args->update);
- if (mp_update.length
- && mp_update.afi == AFI_IP
- && mp_update.safi == SAFI_UNICAST)
- bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
+ if (args->mp_update.length
+ && args->mp_update.afi == AFI_IP
+ && args->mp_update.safi == SAFI_UNICAST)
+ bgp_nlri_parse (peer, NLRI_ATTR_ARG, &args->mp_update);
- if (mp_withdraw.length
- && mp_withdraw.afi == AFI_IP
- && mp_withdraw.safi == SAFI_UNICAST)
- bgp_nlri_parse (peer, NULL, &mp_withdraw);
+ if (args->mp_withdraw.length
+ && args->mp_withdraw.afi == AFI_IP
+ && args->mp_withdraw.safi == SAFI_UNICAST)
+ bgp_nlri_parse (peer, NULL, &args->mp_withdraw);
- if ((attribute_len == 0) && (withdraw.length == 0)
- && (update.length == 0))
+ if ((attribute_len == 0) && (args->withdraw.length == 0)
+ && (args->update.length == 0))
{
/* End-of-RIB received */
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
@@ -966,19 +958,19 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
if (peer->afc[AFI_IP][SAFI_MULTICAST])
{
- if (mp_update.length
- && mp_update.afi == AFI_IP
- && mp_update.safi == SAFI_MULTICAST)
- bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
-
- if (mp_withdraw.length
- && mp_withdraw.afi == AFI_IP
- && mp_withdraw.safi == SAFI_MULTICAST)
- bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
- if (mp_eor
- && mp_withdraw.afi == AFI_IP
- && mp_withdraw.safi == SAFI_MULTICAST)
+ if (args->mp_update.length
+ && args->mp_update.afi == AFI_IP
+ && args->mp_update.safi == SAFI_MULTICAST)
+ bgp_nlri_parse (peer, NLRI_ATTR_ARG, &args->mp_update);
+
+ if (args->mp_withdraw.length
+ && args->mp_withdraw.afi == AFI_IP
+ && args->mp_withdraw.safi == SAFI_MULTICAST)
+ bgp_nlri_parse (peer, NULL, &args->mp_withdraw);
+
+ if (args->mp_eor
+ && args->mp_withdraw.afi == AFI_IP
+ && args->mp_withdraw.safi == SAFI_MULTICAST)
{
/* End-of-RIB received */
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
@@ -996,19 +988,19 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
}
if (peer->afc[AFI_IP6][SAFI_UNICAST])
{
- if (mp_update.length
- && mp_update.afi == AFI_IP6
- && mp_update.safi == SAFI_UNICAST)
- bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
-
- if (mp_withdraw.length
- && mp_withdraw.afi == AFI_IP6
- && mp_withdraw.safi == SAFI_UNICAST)
- bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
- if (mp_eor
- && mp_withdraw.afi == AFI_IP6
- && mp_withdraw.safi == SAFI_UNICAST)
+ if (args->mp_update.length
+ && args->mp_update.afi == AFI_IP6
+ && args->mp_update.safi == SAFI_UNICAST)
+ bgp_nlri_parse (peer, NLRI_ATTR_ARG, &args->mp_update);
+
+ if (args->mp_withdraw.length
+ && args->mp_withdraw.afi == AFI_IP6
+ && args->mp_withdraw.safi == SAFI_UNICAST)
+ bgp_nlri_parse (peer, NULL, &args->mp_withdraw);
+
+ if (args->mp_eor
+ && args->mp_withdraw.afi == AFI_IP6
+ && args->mp_withdraw.safi == SAFI_UNICAST)
{
/* End-of-RIB received */
SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST],
@@ -1026,19 +1018,19 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
}
if (peer->afc[AFI_IP6][SAFI_MULTICAST])
{
- if (mp_update.length
- && mp_update.afi == AFI_IP6
- && mp_update.safi == SAFI_MULTICAST)
- bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
-
- if (mp_withdraw.length
- && mp_withdraw.afi == AFI_IP6
- && mp_withdraw.safi == SAFI_MULTICAST)
- bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
- if (mp_eor
- && mp_withdraw.afi == AFI_IP6
- && mp_withdraw.safi == SAFI_MULTICAST)
+ if (args->mp_update.length
+ && args->mp_update.afi == AFI_IP6
+ && args->mp_update.safi == SAFI_MULTICAST)
+ bgp_nlri_parse (peer, NLRI_ATTR_ARG, &args->mp_update);
+
+ if (args->mp_withdraw.length
+ && args->mp_withdraw.afi == AFI_IP6
+ && args->mp_withdraw.safi == SAFI_MULTICAST)
+ bgp_nlri_parse (peer, NULL, &args->mp_withdraw);
+
+ if (args->mp_eor
+ && args->mp_withdraw.afi == AFI_IP6
+ && args->mp_withdraw.safi == SAFI_MULTICAST)
{
/* End-of-RIB received */
@@ -1054,19 +1046,19 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
}
if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
- if (mp_update.length
- && mp_update.afi == AFI_IP
- && mp_update.safi == SAFI_MPLS_LABELED_VPN)
- bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
-
- if (mp_withdraw.length
- && mp_withdraw.afi == AFI_IP
- && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
- bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
-
- if (mp_eor
- && mp_withdraw.afi == AFI_IP
- && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
+ if (args->mp_update.length
+ && args->mp_update.afi == AFI_IP
+ && args->mp_update.safi == SAFI_MPLS_LABELED_VPN)
+ bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &args->mp_update);
+
+ if (args->mp_withdraw.length
+ && args->mp_withdraw.afi == AFI_IP
+ && args->mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
+ bgp_nlri_parse_vpnv4 (peer, NULL, &args->mp_withdraw);
+
+ if (args->mp_eor
+ && args->mp_withdraw.afi == AFI_IP
+ && args->mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
{
/* End-of-RIB received */
@@ -1083,7 +1075,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
ret = 0 ;
exit_bgp_update_receive:
- bgp_attr_unintern_sub (&attr, true) ; /* true => free extra */
+ bgp_attr_unintern_sub (&args->attr, true) ; /* true => free extra */
return ret ;
}