Skip to content

Commit 42b173f

Browse files
Add successfully parsed attributes to the malformed return value (#171)
* Add successfully parsed attributes to the malformed return value * update update.py for pep8 --------- Co-authored-by: [email protected] <[email protected]>
1 parent 475f34b commit 42b173f

File tree

3 files changed

+107
-83
lines changed

3 files changed

+107
-83
lines changed

yabgp/common/exception.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ class NotificationSent(Exception):
4747

4848
def __init__(self, sub_error, data=''):
4949
try:
50-
super(NotificationSent, self).__init__()
5150
self.msg = self.message % {'sub_error': sub_error, 'data': data}
5251
self.sub_error = sub_error
5352
self.data = data
53+
super(NotificationSent, self).__init__(self.msg)
5454
except Exception:
5555
if _FATAL_EXCEPTION_FORMAT_ERRORS:
5656
raise
@@ -77,6 +77,10 @@ class UpdateMessageError(NotificationSent):
7777
error = 3
7878
message = "BGP Update Message Error, sub error:%(sub_error)s, data:%(data)s"
7979

80+
def __init__(self, sub_error, data='', sub_results=None):
81+
super(UpdateMessageError, self).__init__(sub_error, data)
82+
self.sub_results = sub_results
83+
8084

8185
class HoldTimerExpiredError(NotificationSent):
8286
error = 4

yabgp/message/attribute/linkstate/linkstate.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1313
# License for the specific language governing permissions and limitations
1414
# under the License.
15-
15+
import logging
1616
import struct
1717

1818
import binascii
19-
19+
import traceback
20+
from yabgp.common import constants as bgp_cons
21+
from yabgp.common import exception as excep
2022
from yabgp.message.attribute import Attribute, AttributeFlag, AttributeID
2123

24+
LOG = logging.getLogger()
25+
2226

2327
class LinkState(Attribute):
2428
"""BGP link-state attribute
@@ -61,17 +65,27 @@ def unpack(cls, data, bgpls_pro_id=None):
6165
while data:
6266
type_code, length = struct.unpack('!HH', data[:4])
6367
value = data[4: 4 + length]
64-
if type_code in [1099, 1100, 1158, 1162, 1038] and type_code in cls.registered_tlvs:
65-
tlvs.append(cls.registered_tlvs[type_code].unpack(value, bgpls_pro_id).dict())
66-
elif type_code in cls.registered_tlvs:
67-
tlvs.append(cls.registered_tlvs[type_code].unpack(value).dict())
68-
else:
69-
tlvs.append(
70-
{
71-
'type': type_code,
72-
'value': str(binascii.b2a_hex(value))
73-
}
74-
)
68+
try:
69+
if type_code in [1099, 1100, 1158, 1162, 1038] and type_code in cls.registered_tlvs:
70+
tlvs.append(cls.registered_tlvs[type_code].unpack(value, bgpls_pro_id).dict())
71+
elif type_code in cls.registered_tlvs:
72+
tlvs.append(cls.registered_tlvs[type_code].unpack(value).dict())
73+
else:
74+
tlvs.append(
75+
{
76+
'type': type_code,
77+
'value': str(binascii.b2a_hex(value))
78+
}
79+
)
80+
except Exception as e:
81+
LOG.error(e)
82+
error_str = traceback.format_exc()
83+
LOG.debug(error_str)
84+
raise excep.UpdateMessageError(
85+
sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST,
86+
data=value,
87+
sub_results=cls(value=tlvs))
88+
7589
data = data[4 + length:]
7690

7791
return cls(value=tlvs)

yabgp/message/update.py

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515

1616
"""BGP Update Message"""
1717

18-
import struct
19-
import traceback
20-
import logging
2118
import binascii
22-
19+
import logging
2320
import netaddr
24-
21+
import struct
22+
import traceback
2523
from yabgp.common import exception as excep
2624
from yabgp.common import constants as bgp_cons
2725
from yabgp.message.attribute import AttributeFlag
@@ -191,6 +189,7 @@ def parse(cls, t, msg_hex, asn4=False, add_path_remote=False, add_path_local=Fal
191189
LOG.error(e)
192190
results['sub_error'] = e.sub_error
193191
results['err_data'] = e.data
192+
results['attr'] = e.sub_results
194193
except Exception as e:
195194
LOG.error(e)
196195
error_str = traceback.format_exc()
@@ -291,9 +290,9 @@ def parse_attributes(data, asn4=False):
291290
postfix = data
292291
bgpls_pro_id = None
293292
bgpls_attr = None
294-
while len(postfix) > 0:
295293

296-
try:
294+
try:
295+
while len(postfix) > 0:
297296
flags, type_code = struct.unpack('!BB', postfix[:2])
298297

299298
if flags & AttributeFlag.EXTENDED_LENGTH:
@@ -307,103 +306,110 @@ def parse_attributes(data, asn4=False):
307306
attr_len = ord(postfix[2])
308307
attr_value = postfix[3:3 + attr_len]
309308
postfix = postfix[3 + attr_len:] # Next attribute
310-
except Exception as e:
311-
LOG.error(e)
312-
error_str = traceback.format_exc()
313-
LOG.debug(error_str)
314-
raise excep.UpdateMessageError(
315-
sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST,
316-
data='')
317309

318-
if type_code == bgp_cons.BGPTYPE_ORIGIN:
310+
if type_code == bgp_cons.BGPTYPE_ORIGIN:
319311

320-
decode_value = Origin.parse(value=attr_value)
312+
decode_value = Origin.parse(value=attr_value)
321313

322-
elif type_code == bgp_cons.BGPTYPE_AS_PATH:
314+
elif type_code == bgp_cons.BGPTYPE_AS_PATH:
323315

324-
decode_value = ASPath.parse(value=attr_value, asn4=asn4)
316+
decode_value = ASPath.parse(value=attr_value, asn4=asn4)
325317

326-
elif type_code == bgp_cons.BGPTYPE_NEXT_HOP:
318+
elif type_code == bgp_cons.BGPTYPE_NEXT_HOP:
327319

328-
decode_value = NextHop.parse(value=attr_value)
320+
decode_value = NextHop.parse(value=attr_value)
329321

330-
elif type_code == bgp_cons.BGPTYPE_MULTI_EXIT_DISC:
322+
elif type_code == bgp_cons.BGPTYPE_MULTI_EXIT_DISC:
331323

332-
decode_value = MED.parse(value=attr_value)
324+
decode_value = MED.parse(value=attr_value)
333325

334-
elif type_code == bgp_cons.BGPTYPE_LOCAL_PREF:
326+
elif type_code == bgp_cons.BGPTYPE_LOCAL_PREF:
335327

336-
decode_value = LocalPreference.parse(value=attr_value)
328+
decode_value = LocalPreference.parse(value=attr_value)
337329

338-
elif type_code == bgp_cons.BGPTYPE_ATOMIC_AGGREGATE:
330+
elif type_code == bgp_cons.BGPTYPE_ATOMIC_AGGREGATE:
339331

340-
decode_value = AtomicAggregate.parse(value=attr_value)
332+
decode_value = AtomicAggregate.parse(value=attr_value)
341333

342-
elif type_code == bgp_cons.BGPTYPE_AGGREGATOR:
334+
elif type_code == bgp_cons.BGPTYPE_AGGREGATOR:
343335

344-
decode_value = Aggregator.parse(value=attr_value, asn4=asn4)
336+
decode_value = Aggregator.parse(value=attr_value, asn4=asn4)
345337

346-
elif type_code == bgp_cons.BGPTYPE_COMMUNITIES:
338+
elif type_code == bgp_cons.BGPTYPE_COMMUNITIES:
347339

348-
decode_value = Community.parse(value=attr_value)
340+
decode_value = Community.parse(value=attr_value)
349341

350-
elif type_code == bgp_cons.BGPTYPE_ORIGINATOR_ID:
342+
elif type_code == bgp_cons.BGPTYPE_ORIGINATOR_ID:
351343

352-
decode_value = OriginatorID.parse(value=attr_value)
344+
decode_value = OriginatorID.parse(value=attr_value)
353345

354-
elif type_code == bgp_cons.BGPTYPE_CLUSTER_LIST:
346+
elif type_code == bgp_cons.BGPTYPE_CLUSTER_LIST:
355347

356-
decode_value = ClusterList.parse(value=attr_value)
348+
decode_value = ClusterList.parse(value=attr_value)
357349

358-
elif type_code == bgp_cons.BGPTYPE_NEW_AS_PATH:
350+
elif type_code == bgp_cons.BGPTYPE_NEW_AS_PATH:
359351

360-
decode_value = ASPath.parse(value=attr_value, asn4=True)
352+
decode_value = ASPath.parse(value=attr_value, asn4=True)
361353

362-
elif type_code == bgp_cons.BGPTYPE_NEW_AGGREGATOR:
354+
elif type_code == bgp_cons.BGPTYPE_NEW_AGGREGATOR:
363355

364-
decode_value = Aggregator.parse(value=attr_value, asn4=True)
356+
decode_value = Aggregator.parse(value=attr_value, asn4=True)
365357

366-
elif type_code == bgp_cons.BGPTYPE_LARGE_COMMUNITY:
358+
elif type_code == bgp_cons.BGPTYPE_LARGE_COMMUNITY:
367359

368-
decode_value = LargeCommunity.parse(value=attr_value)
360+
decode_value = LargeCommunity.parse(value=attr_value)
369361

370-
elif type_code == bgp_cons.BGPTYPE_MP_REACH_NLRI:
371-
decode_value = MpReachNLRI.parse(value=attr_value)
372-
if decode_value['nlri'][0] and type(decode_value['nlri'][0]) is dict:
373-
if decode_value['nlri'][0].get("protocol_id"):
374-
bgpls_pro_id = decode_value['nlri'][0]["protocol_id"]
362+
elif type_code == bgp_cons.BGPTYPE_MP_REACH_NLRI:
363+
decode_value = MpReachNLRI.parse(value=attr_value)
364+
if decode_value['nlri'][0] and type(decode_value['nlri'][0]) is dict:
365+
if decode_value['nlri'][0].get("protocol_id"):
366+
bgpls_pro_id = decode_value['nlri'][0]["protocol_id"]
375367

376-
elif type_code == bgp_cons.BGPTYPE_MP_UNREACH_NLRI:
377-
decode_value = MpUnReachNLRI.parse(value=attr_value)
368+
elif type_code == bgp_cons.BGPTYPE_MP_UNREACH_NLRI:
369+
decode_value = MpUnReachNLRI.parse(value=attr_value)
378370

379-
elif type_code == bgp_cons.BGPTYPE_EXTENDED_COMMUNITY:
380-
decode_value = ExtCommunity.parse(value=attr_value)
371+
elif type_code == bgp_cons.BGPTYPE_EXTENDED_COMMUNITY:
372+
decode_value = ExtCommunity.parse(value=attr_value)
381373

382-
elif type_code == bgp_cons.BGPTYPE_PMSI_TUNNEL:
383-
decode_value = PMSITunnel.parse(value=attr_value)
384-
pmsi_hex = attr_value
374+
elif type_code == bgp_cons.BGPTYPE_PMSI_TUNNEL:
375+
decode_value = PMSITunnel.parse(value=attr_value)
376+
pmsi_hex = attr_value
385377

386-
elif type_code == bgp_cons.BGPTYPE_LINK_STATE:
387-
if bgpls_pro_id:
388-
attributes.update(LinkState.unpack(bgpls_pro_id=bgpls_pro_id, data=attr_value).dict())
389-
else:
390-
bgpls_attr = attr_value
391-
continue
378+
elif type_code == bgp_cons.BGPTYPE_LINK_STATE:
379+
if bgpls_pro_id:
380+
attributes.update(LinkState.unpack(bgpls_pro_id=bgpls_pro_id, data=attr_value).dict())
381+
else:
382+
bgpls_attr = attr_value
383+
continue
392384

393-
elif type_code == bgp_cons.BGPTYPE_BGP_PREFIX_SID:
394-
decode_value = BGPPrefixSID.unpack(data=attr_value)
385+
elif type_code == bgp_cons.BGPTYPE_BGP_PREFIX_SID:
386+
decode_value = BGPPrefixSID.unpack(data=attr_value)
395387

396-
else:
397-
decode_value = binascii.b2a_hex(attr_value).decode('utf-8')
398-
attributes[type_code] = decode_value
388+
else:
389+
decode_value = binascii.b2a_hex(attr_value).decode('utf-8')
390+
attributes[type_code] = decode_value
399391

400-
if bgpls_attr:
401-
attributes.update(LinkState.unpack(bgpls_pro_id=bgpls_pro_id, data=bgpls_attr).dict())
392+
if bgpls_attr:
393+
attributes.update(LinkState.unpack(bgpls_pro_id=bgpls_pro_id, data=bgpls_attr).dict())
402394

403-
evpn_overlay = EVPN.signal_evpn_overlay(attributes)
404-
if evpn_overlay['evpn'] and evpn_overlay['encap_ec']:
405-
if bgp_cons.BGPTYPE_PMSI_TUNNEL in attributes:
406-
attributes[bgp_cons.BGPTYPE_PMSI_TUNNEL] = PMSITunnel.parse(value=pmsi_hex, evpn_overlay=evpn_overlay)
395+
evpn_overlay = EVPN.signal_evpn_overlay(attributes)
396+
if evpn_overlay['evpn'] and evpn_overlay['encap_ec']:
397+
if bgp_cons.BGPTYPE_PMSI_TUNNEL in attributes:
398+
attributes[bgp_cons.BGPTYPE_PMSI_TUNNEL] = PMSITunnel.parse(value=pmsi_hex,
399+
evpn_overlay=evpn_overlay)
400+
except excep.UpdateMessageError as e:
401+
raise excep.UpdateMessageError(
402+
sub_error=e.sub_error,
403+
data=e.data,
404+
sub_results=attributes)
405+
except Exception as e:
406+
LOG.error(e)
407+
error_str = traceback.format_exc()
408+
LOG.debug(error_str)
409+
raise excep.UpdateMessageError(
410+
sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST,
411+
data='',
412+
sub_results=attributes)
407413
return attributes
408414

409415
@staticmethod

0 commit comments

Comments
 (0)