diff options
-rw-r--r-- | packet/bgp/bgp.go | 83 | ||||
-rw-r--r-- | packet/bgp/bgp_test.go | 9 | ||||
-rw-r--r-- | server/fsm.go | 4 |
3 files changed, 94 insertions, 2 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index 0e3a405a..4cfcf35f 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -3528,6 +3528,89 @@ const ( BGP_ERROR_SUB_INVALID_MESSAGE_LENGTH ) +type NotificationErrorCode uint16 + +func (c NotificationErrorCode) String() string { + code := uint8(uint16(c) >> 8) + subcode := uint8(uint16(c) & 0xff) + UNDEFINED := "undefined" + codeStr := UNDEFINED + subcodeList := []string{} + switch code { + case BGP_ERROR_MESSAGE_HEADER_ERROR: + codeStr = "header" + subcodeList = []string{ + UNDEFINED, + "connection not synchronized", + "bad message length", + "bad message type"} + case BGP_ERROR_OPEN_MESSAGE_ERROR: + codeStr = "open" + subcodeList = []string{ + UNDEFINED, + "unsupported version number", + "bad peer as", + "bad bgp identifier", + "unsupported optional parameter", + "deprecated authentication failure", + "unacceptable hold time", + "unsupported capability"} + case BGP_ERROR_UPDATE_MESSAGE_ERROR: + codeStr = "update" + subcodeList = []string{ + UNDEFINED, + "malformed attribute list", + "unrecognized well known attribute", + "missing well known attribute", + "attribute flags error", + "attribute length error", + "invalid origin attribute", + "deprecated routing loop", + "invalid next hop attribute", + "optional attribute error", + "invalid network field", + "sub malformed as path"} + case BGP_ERROR_HOLD_TIMER_EXPIRED: + codeStr = "hold timer expired" + subcodeList = []string{ + UNDEFINED, + "hold timer expired"} + case BGP_ERROR_FSM_ERROR: + codeStr = "fsm" + subcodeList = []string{ + UNDEFINED, + "receive unexpected message in opensent state", + "receive unexpected message in openconfirm state", + "receive unexpected message in established state"} + case BGP_ERROR_CEASE: + codeStr = "cease" + subcodeList = []string{ + UNDEFINED, + "maximum number of prefixes reached", + "administrative shutdown", + "peer deconfigured", + "administrative reset", + "connection rejected", + "other configuration change", + "connection collision resolution", + "out of resources"} + case BGP_ERROR_ROUTE_REFRESH_MESSAGE_ERROR: + codeStr = "route refresh" + subcodeList = []string{"invalid message length"} + } + subcodeStr := func(idx uint8, l []string) string { + if len(l) == 0 || int(idx) > len(l)-1 { + return UNDEFINED + } + return l[idx] + }(subcode, subcodeList) + return fmt.Sprintf("code %v(%v) subcode %v(%v)", code, codeStr, subcode, subcodeStr) +} + +func NewNotificationErrorCode(code, subcode uint8) NotificationErrorCode { + return NotificationErrorCode(uint16(code)<<8 | uint16(subcode)) +} + var pathAttrFlags map[BGPAttrType]BGPAttrFlag = map[BGPAttrType]BGPAttrFlag{ BGP_ATTR_TYPE_ORIGIN: BGP_ATTR_FLAG_TRANSITIVE, BGP_ATTR_TYPE_AS_PATH: BGP_ATTR_FLAG_TRANSITIVE, diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go index af4e2938..48366b61 100644 --- a/packet/bgp/bgp_test.go +++ b/packet/bgp/bgp_test.go @@ -446,3 +446,12 @@ func Test_FlowSpecNlriL2(t *testing.T) { t.Log(bytes.Equal(buf1, buf2)) } } + +func Test_NotificationErrorCode(t *testing.T) { + // boundary check + NewNotificationErrorCode(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_TYPE).String() + NewNotificationErrorCode(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_TYPE+1).String() + NewNotificationErrorCode(BGP_ERROR_MESSAGE_HEADER_ERROR, 0).String() + NewNotificationErrorCode(0, BGP_ERROR_SUB_BAD_MESSAGE_TYPE).String() + NewNotificationErrorCode(BGP_ERROR_ROUTE_REFRESH_MESSAGE_ERROR+1, 0).String() +} diff --git a/server/fsm.go b/server/fsm.go index 351a8e99..8838ac23 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -671,7 +671,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) { "Data": body.Data, }).Warn("received notification") - sendToErrorCh(FsmStateReason(fmt.Sprintf("%s(%d/%d)", FSM_NOTIFICATION_RECV, body.ErrorCode, body.ErrorSubcode))) + sendToErrorCh(FsmStateReason(fmt.Sprintf("%s %s", FSM_NOTIFICATION_RECV, bgp.NewNotificationErrorCode(body.ErrorCode, body.ErrorSubcode).String()))) return nil, nil } } @@ -1048,7 +1048,7 @@ func (h *FSMHandler) sendMessageloop() error { "Data": m, }).Warn("sent notification") body := m.Body.(*bgp.BGPNotification) - h.errorCh <- FsmStateReason(fmt.Sprintf("%s(%d/%d)", FSM_NOTIFICATION_SENT, body.ErrorCode, body.ErrorSubcode)) + h.errorCh <- FsmStateReason(fmt.Sprintf("%s %s", FSM_NOTIFICATION_SENT, bgp.NewNotificationErrorCode(body.ErrorCode, body.ErrorSubcode).String())) conn.Close() return fmt.Errorf("closed") case bgp.BGP_MSG_UPDATE: |