summaryrefslogtreecommitdiffhomepage
path: root/server/peer.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/peer.go')
-rw-r--r--server/peer.go243
1 files changed, 124 insertions, 119 deletions
diff --git a/server/peer.go b/server/peer.go
index 8c62d105..194998fb 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -288,79 +288,93 @@ func (peer *Peer) sendMessages(msgs []*bgp.BGPMessage) {
}
}
-func (peer *Peer) handleREST(restReq *api.RestRequest) {
- result := &api.RestResponse{}
- switch restReq.RequestType {
+func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
+ result := &api.GrpcResponse{}
+ switch grpcReq.RequestType {
case api.REQ_GLOBAL_ADD, api.REQ_GLOBAL_DELETE:
- rf := restReq.RouteFamily
- prefixes := restReq.Data["prefix"].([]string)
+ rf := grpcReq.RouteFamily
+ prefix := grpcReq.Data["prefix"].(string)
var isWithdraw bool
- if restReq.RequestType == api.REQ_GLOBAL_DELETE {
+ if grpcReq.RequestType == api.REQ_GLOBAL_DELETE {
isWithdraw = true
}
- pList := make([]table.Path, 0, len(prefixes))
- for _, prefix := range prefixes {
- var nlri bgp.AddrPrefixInterface
- pattr := make([]bgp.PathAttributeInterface, 0)
- pattr = append(pattr, bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP))
- asparam := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{peer.peerInfo.AS})
- pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam}))
-
- if rf == bgp.RF_IPv4_UC {
- ip, net, _ := net.ParseCIDR(prefix)
- if ip.To4() == nil {
- result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", prefix)
- restReq.ResponseCh <- result
- close(restReq.ResponseCh)
- return
- }
- ones, _ := net.Mask.Size()
- nlri = &bgp.NLRInfo{
- IPAddrPrefix: *bgp.NewIPAddrPrefix(uint8(ones), ip.String()),
- }
+ var nlri bgp.AddrPrefixInterface
+ pattr := make([]bgp.PathAttributeInterface, 0)
+ pattr = append(pattr, bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP))
+ asparam := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{peer.peerInfo.AS})
+ pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam}))
- pattr = append(pattr, bgp.NewPathAttributeNextHop("0.0.0.0"))
-
- } else if rf == bgp.RF_IPv6_UC {
- ip, net, _ := net.ParseCIDR(prefix)
- if ip.To16() == nil {
- result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", prefix)
- restReq.ResponseCh <- result
- close(restReq.ResponseCh)
- return
- }
- ones, _ := net.Mask.Size()
- nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
+ if rf == bgp.RF_IPv4_UC {
+ ip, net, _ := net.ParseCIDR(prefix)
+ if ip.To4() == nil {
+ result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return
+ }
+ ones, _ := net.Mask.Size()
+ nlri = &bgp.NLRInfo{
+ IPAddrPrefix: *bgp.NewIPAddrPrefix(uint8(ones), ip.String()),
+ }
- pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri}))
+ pattr = append(pattr, bgp.NewPathAttributeNextHop("0.0.0.0"))
- } else {
- result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf)
- restReq.ResponseCh <- result
- close(restReq.ResponseCh)
+ } else if rf == bgp.RF_IPv6_UC {
+ ip, net, _ := net.ParseCIDR(prefix)
+ if ip.To16() == nil {
+ result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
return
}
+ ones, _ := net.Mask.Size()
+ nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
- p := table.CreatePath(peer.peerInfo, nlri, pattr, isWithdraw, time.Now())
- pList = append(pList, p)
+ pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri}))
+
+ } else {
+ result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return
}
+ p := table.CreatePath(peer.peerInfo, nlri, pattr, isWithdraw, time.Now())
+
pm := &peerMsg{
msgType: PEER_MSG_PATH,
- msgData: pList,
+ msgData: []table.Path{p},
}
peer.peerMsgCh <- pm
case api.REQ_LOCAL_RIB, api.REQ_GLOBAL_RIB:
- // just empty so we use ipv4 for any route family
- j, _ := json.Marshal(table.NewIPv4Table(0))
- if peer.fsm.adminState != ADMIN_STATE_DOWN {
- if t, ok := peer.rib.Tables[restReq.RouteFamily]; ok {
- j, _ = json.Marshal(t)
+ if peer.fsm.adminState == ADMIN_STATE_DOWN {
+ close(grpcReq.ResponseCh)
+ return
+ }
+ if t, ok := peer.rib.Tables[grpcReq.RouteFamily]; ok {
+ type table struct {
+ Destinations []*api.Destination
+ }
+ var tt table
+ j, _ := json.Marshal(t)
+ err := json.Unmarshal(j, &tt)
+ if err != nil {
+ result := &api.GrpcResponse{}
+ result.ResponseErr = err
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return
+ }
+ for _, dst := range tt.Destinations {
+ result := &api.GrpcResponse{}
+ result.Data = dst
+ grpcReq.ResponseCh <- result
}
+ close(grpcReq.ResponseCh)
+ return
}
- result.Data = j
case api.REQ_NEIGHBOR_SHUTDOWN:
peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil)
case api.REQ_NEIGHBOR_RESET:
@@ -368,40 +382,55 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) {
peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil)
case api.REQ_NEIGHBOR_SOFT_RESET, api.REQ_NEIGHBOR_SOFT_RESET_IN:
// soft-reconfiguration inbound
- peer.sendPathsToSiblings(peer.adjRib.GetInPathList(restReq.RouteFamily))
- if restReq.RequestType == api.REQ_NEIGHBOR_SOFT_RESET_IN {
+ peer.sendPathsToSiblings(peer.adjRib.GetInPathList(grpcReq.RouteFamily))
+ if grpcReq.RequestType == api.REQ_NEIGHBOR_SOFT_RESET_IN {
break
}
fallthrough
case api.REQ_NEIGHBOR_SOFT_RESET_OUT:
- pathList := peer.adjRib.GetOutPathList(restReq.RouteFamily)
+ pathList := peer.adjRib.GetOutPathList(grpcReq.RouteFamily)
peer.sendMessages(table.CreateUpdateMsgFromPaths(pathList))
case api.REQ_ADJ_RIB_IN, api.REQ_ADJ_RIB_OUT:
- rf := restReq.RouteFamily
- if restReq.RequestType == api.REQ_ADJ_RIB_IN {
- paths := peer.adjRib.GetInPathList(rf)
- j, _ := json.Marshal(paths)
- result.Data = j
+ rf := grpcReq.RouteFamily
+ var paths []table.Path
+
+ if grpcReq.RequestType == api.REQ_ADJ_RIB_IN {
+ paths = peer.adjRib.GetInPathList(rf)
log.Debugf("RouteFamily=%v adj-rib-in found : %d", rf.String(), len(paths))
} else {
- paths := peer.adjRib.GetOutPathList(rf)
- j, _ := json.Marshal(paths)
- result.Data = j
+ paths = peer.adjRib.GetOutPathList(rf)
log.Debugf("RouteFamily=%v adj-rib-out found : %d", rf.String(), len(paths))
}
+
+ for _, p := range paths {
+ result := &api.GrpcResponse{}
+ path := &api.Path{}
+ j, _ := json.Marshal(p)
+ err := json.Unmarshal(j, path)
+ if err != nil {
+ result.ResponseErr = err
+ } else {
+ result.Data = path
+ }
+ grpcReq.ResponseCh <- result
+ }
+ close(grpcReq.ResponseCh)
+ return
case api.REQ_NEIGHBOR_ENABLE, api.REQ_NEIGHBOR_DISABLE:
- r := make(map[string]string)
- if restReq.RequestType == api.REQ_NEIGHBOR_ENABLE {
+ var err api.Error
+ if grpcReq.RequestType == api.REQ_NEIGHBOR_ENABLE {
select {
case peer.fsm.adminStateCh <- ADMIN_STATE_UP:
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": peer.peerConfig.NeighborAddress,
}).Debug("ADMIN_STATE_UP requested")
- r["result"] = "ADMIN_STATE_UP"
+ err.Code = api.Error_SUCCESS
+ err.Msg = "ADMIN_STATE_UP"
default:
log.Warning("previous request is still remaining. : ", peer.peerConfig.NeighborAddress)
- r["result"] = "previous request is still remaining"
+ err.Code = api.Error_FAIL
+ err.Msg = "previous request is still remaining"
}
} else {
select {
@@ -410,17 +439,18 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) {
"Topic": "Peer",
"Key": peer.peerConfig.NeighborAddress,
}).Debug("ADMIN_STATE_DOWN requested")
- r["result"] = "ADMIN_STATE_DOWN"
+ err.Code = api.Error_SUCCESS
+ err.Msg = "ADMIN_STATE_DOWN"
default:
log.Warning("previous request is still remaining. : ", peer.peerConfig.NeighborAddress)
- r["result"] = "previous request is still remaining"
+ err.Code = api.Error_FAIL
+ err.Msg = "previous request is still remaining"
}
}
- j, _ := json.Marshal(r)
- result.Data = j
+ result.Data = err
}
- restReq.ResponseCh <- result
- close(restReq.ResponseCh)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
}
func (peer *Peer) sendUpdateMsgFromPaths(pList []table.Path) {
@@ -626,7 +656,7 @@ func (peer *Peer) handleServerMsg(m *serverMsg) {
log.Warning("can not find peer: ", d.Address.String())
}
case SRV_MSG_API:
- peer.handleREST(m.msgData.(*api.RestRequest))
+ peer.handleGrpc(m.msgData.(*api.GrpcRequest))
case SRV_MSG_POLICY_UPDATED:
log.Debug("policy updated")
d := m.msgData.(map[string]*policy.Policy)
@@ -797,30 +827,29 @@ func (peer *Peer) PassConn(conn *net.TCPConn) {
}
func (peer *Peer) MarshalJSON() ([]byte, error) {
+ p, err := peer.ToGrpc()
+ if err != nil {
+ return nil, err
+ }
+ return json.Marshal(p)
+}
+
+func (peer *Peer) ToGrpc() (*api.Peer, error) {
f := peer.fsm
c := f.peerConfig
- p := make(map[string]interface{})
- capList := make([]int, 0)
+ capList := make([]int32, 0, len(peer.capMap))
for k, _ := range peer.capMap {
- capList = append(capList, int(k))
+ capList = append(capList, int32(k))
}
- p["conf"] = struct {
- RemoteIP string `json:"remote_ip"`
- Id string `json:"id"`
- RemoteAS uint32 `json:"remote_as"`
- CapRefresh bool `json:"cap_refresh"`
- CapEnhancedRefresh bool `json:"cap_enhanced_refresh"`
- RemoteCap []int
- LocalCap []int
- }{
- RemoteIP: c.NeighborAddress.String(),
+ conf := &api.PeerConf{
+ RemoteIp: c.NeighborAddress.String(),
Id: peer.peerInfo.ID.To4().String(),
- RemoteAS: c.PeerAs,
+ RemoteAs: c.PeerAs,
RemoteCap: capList,
- LocalCap: []int{int(bgp.BGP_CAP_MULTIPROTOCOL), int(bgp.BGP_CAP_ROUTE_REFRESH), int(bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER)},
+ LocalCap: []int32{int32(bgp.BGP_CAP_MULTIPROTOCOL), int32(bgp.BGP_CAP_ROUTE_REFRESH), int32(bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER)},
}
s := c.BgpNeighborCommonState
@@ -845,34 +874,7 @@ func (peer *Peer) MarshalJSON() ([]byte, error) {
}
}
- p["info"] = struct {
- BgpState string `json:"bgp_state"`
- AdminState string
- FsmEstablishedTransitions uint32 `json:"fsm_established_transitions"`
- TotalMessageOut uint32 `json:"total_message_out"`
- TotalMessageIn uint32 `json:"total_message_in"`
- UpdateMessageOut uint32 `json:"update_message_out"`
- UpdateMessageIn uint32 `json:"update_message_in"`
- KeepAliveMessageOut uint32 `json:"keepalive_message_out"`
- KeepAliveMessageIn uint32 `json:"keepalive_message_in"`
- OpenMessageOut uint32 `json:"open_message_out"`
- OpenMessageIn uint32 `json:"open_message_in"`
- NotificationOut uint32 `json:"notification_out"`
- NotificationIn uint32 `json:"notification_in"`
- RefreshMessageOut uint32 `json:"refresh_message_out"`
- RefreshMessageIn uint32 `json:"refresh_message_in"`
- DiscardedOut uint32
- DiscardedIn uint32
- Uptime int64 `json:"uptime"`
- Downtime int64 `json:"downtime"`
- LastError string `json:"last_error"`
- Received uint32
- Accepted uint32
- Advertized uint32
- OutQ int
- Flops uint32
- }{
-
+ info := &api.PeerInfo{
BgpState: f.state.String(),
AdminState: f.adminState.String(),
FsmEstablishedTransitions: s.EstablishedCount,
@@ -895,9 +897,12 @@ func (peer *Peer) MarshalJSON() ([]byte, error) {
Received: received,
Accepted: accepted,
Advertized: advertized,
- OutQ: len(peer.outgoing),
+ OutQ: uint32(len(peer.outgoing)),
Flops: s.Flops,
}
- return json.Marshal(p)
+ return &api.Peer{
+ Conf: conf,
+ Info: info,
+ }, nil
}