summaryrefslogtreecommitdiffhomepage
path: root/packet/bgp/bgp.go
diff options
context:
space:
mode:
authorSatoshi Fujimoto <satoshi.fujimoto7@gmail.com>2017-07-31 16:35:40 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-09-29 15:05:43 +0900
commite2e8a840e67868cc3070530fe5e1a0dc3edf73f1 (patch)
tree2a7f3ed7b2fe8e384aafabd051f09b8dc875b04b /packet/bgp/bgp.go
parent4158d82bf6129e49b7fbc40809a54ca44820f581 (diff)
packet/bgp: Return ErrorHandling in decoding/validating BGPUpdate
For Revised Error Handling(RFC7606), this patch modifies the BGPUpdate message decoder/validator to return ErrorHandling according to what was detected as an error. In addition, this patch adds some validation defined in RFC7606. Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com>
Diffstat (limited to 'packet/bgp/bgp.go')
-rw-r--r--packet/bgp/bgp.go43
1 files changed, 35 insertions, 8 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index c8050ab5..7e60b96e 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -7817,6 +7817,7 @@ type BGPUpdate struct {
}
func (msg *BGPUpdate) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
+ var strongestError error
// cache error codes
eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
@@ -7870,20 +7871,46 @@ func (msg *BGPUpdate) DecodeFromBytes(data []byte, options ...*MarshallingOption
msg.PathAttributes = []PathAttributeInterface{}
for pathlen := msg.TotalPathAttributeLen; pathlen > 0; {
+ var e error
+ if pathlen < 3 {
+ e = NewMessageErrorWithErrorHandling(
+ eCode, BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR, data, ERROR_HANDLING_TREAT_AS_WITHDRAW, nil, "insufficient data to decode")
+ if e.(*MessageError).Stronger(strongestError) {
+ strongestError = e
+ }
+ data = data[pathlen:]
+ break
+ }
p, err := GetPathAttribute(data)
if err != nil {
return err
}
+
err = p.DecodeFromBytes(data, options...)
if err != nil {
- return err
+ e = err.(*MessageError)
+ if e.(*MessageError).SubTypeCode == BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR {
+ e.(*MessageError).ErrorHandling = ERROR_HANDLING_TREAT_AS_WITHDRAW
+ } else {
+ e.(*MessageError).ErrorHandling = getErrorHandlingFromPathAttribute(p.GetType())
+ e.(*MessageError).ErrorAttribute = &p
+ }
+ if e.(*MessageError).Stronger(strongestError) {
+ strongestError = e
+ }
}
pathlen -= uint16(p.Len(options...))
if len(data) < p.Len(options...) {
- return NewMessageError(eCode, BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR, data, "attribute length is short")
+ e = NewMessageErrorWithErrorHandling(
+ eCode, BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR, data, ERROR_HANDLING_TREAT_AS_WITHDRAW, nil, "attribute length is short")
+ if e.(*MessageError).Stronger(strongestError) {
+ strongestError = e
+ }
}
data = data[p.Len(options...):]
- msg.PathAttributes = append(msg.PathAttributes, p)
+ if e == nil || e.(*MessageError).ErrorHandling != ERROR_HANDLING_ATTRIBUTE_DISCARD {
+ msg.PathAttributes = append(msg.PathAttributes, p)
+ }
}
msg.NLRI = make([]*IPAddrPrefix, 0)
@@ -7897,11 +7924,14 @@ func (msg *BGPUpdate) DecodeFromBytes(data []byte, options ...*MarshallingOption
if len(data) < n.Len(options...)+addpathLen {
return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, nil, "NLRI length is short")
}
+ if n.Len(options...) > 32 {
+ return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, nil, "NLRI length is too long")
+ }
data = data[n.Len(options...)+addpathLen:]
msg.NLRI = append(msg.NLRI, n)
}
- return nil
+ return strongestError
}
func (msg *BGPUpdate) Serialize(options ...*MarshallingOption) ([]byte, error) {
@@ -8125,10 +8155,7 @@ func parseBody(h *BGPHeader, data []byte, options ...*MarshallingOption) (*BGPMe
return nil, NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_TYPE, nil, "unknown message type")
}
err := msg.Body.DecodeFromBytes(data, options...)
- if err != nil {
- return nil, err
- }
- return msg, nil
+ return msg, err
}
func ParseBGPMessage(data []byte, options ...*MarshallingOption) (*BGPMessage, error) {