summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-06-27 23:28:54 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-07-01 21:24:40 +0900
commitccfded2fee746664b576df0a068aec727cb5fae5 (patch)
treec52f10638ad74bca773a7e6120a2edf507670221 /server
parent8a3724c7fdd6f02311e669f2aa0fc28190faaf66 (diff)
server/cli: support add/delete EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG route
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r--server/server.go140
1 files changed, 85 insertions, 55 deletions
diff --git a/server/server.go b/server/server.go
index 29f3a1fd..437e90da 100644
--- a/server/server.go
+++ b/server/server.go
@@ -668,36 +668,32 @@ func (server *BgpServer) checkNeighborRequest(grpcReq *GrpcRequest) (*Peer, erro
}
func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*table.Path {
- pathList := []*table.Path{}
+ var isWithdraw bool
+ var p *table.Path
+ var nlri bgp.AddrPrefixInterface
result := &GrpcResponse{}
+ 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{peerInfo.AS})
+ pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam}))
+
rf := grpcReq.RouteFamily
path, ok := grpcReq.Data.(*api.Path)
if !ok {
result.ResponseErr = fmt.Errorf("type assertion failed")
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
+ goto ERR
}
- var isWithdraw bool
if grpcReq.RequestType == REQ_GLOBAL_DELETE {
isWithdraw = true
}
- 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{peerInfo.AS})
- pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam}))
-
switch rf {
case bgp.RF_IPv4_UC:
ip, net, _ := net.ParseCIDR(path.Nlri.Prefix)
if ip.To4() == nil {
result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", path.Nlri.Prefix)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
+ goto ERR
}
ones, _ := net.Mask.Size()
nlri = &bgp.NLRInfo{
@@ -711,9 +707,7 @@ func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*t
ip, net, _ := net.ParseCIDR(path.Nlri.Prefix)
if ip.To16() == nil {
result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", path.Nlri.Prefix)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
+ goto ERR
}
ones, _ := net.Mask.Size()
nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
@@ -721,45 +715,80 @@ func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*t
pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri}))
case bgp.RF_EVPN:
- mac, err := net.ParseMAC(path.Nlri.EvpnNlri.MacIpAdv.MacAddr)
- if err != nil {
- result.ResponseErr = fmt.Errorf("Invalid mac: %s", path.Nlri.EvpnNlri.MacIpAdv.MacAddr)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
- }
- ip := net.ParseIP(path.Nlri.EvpnNlri.MacIpAdv.IpAddr)
- if ip == nil {
- result.ResponseErr = fmt.Errorf("Invalid ip prefix: %s", path.Nlri.EvpnNlri.MacIpAdv.IpAddr)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
- }
- iplen := net.IPv4len * 8
- if ip.To4() == nil {
- iplen = net.IPv6len * 8
+ if peerInfo.AS > (1<<16 - 1) {
+ result.ResponseErr = fmt.Errorf("evpn path can't be created in 4byte-AS env")
}
+ asn := uint16(peerInfo.AS)
+ routerId := peerInfo.LocalID
+ var eTag uint32
- macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
- RD: bgp.NewRouteDistinguisherTwoOctetAS(0, 0),
- ESI: bgp.EthernetSegmentIdentifier{
- Type: bgp.ESI_ARBITRARY,
- },
- MacAddressLength: 48,
- MacAddress: mac,
- IPAddressLength: uint8(iplen),
- IPAddress: ip,
- Labels: []uint32{0},
+ switch path.Nlri.EvpnNlri.Type {
+ case bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT:
+ mac, err := net.ParseMAC(path.Nlri.EvpnNlri.MacIpAdv.MacAddr)
+ if err != nil {
+ result.ResponseErr = fmt.Errorf("Invalid mac: %s", path.Nlri.EvpnNlri.MacIpAdv.MacAddr)
+ goto ERR
+ }
+ var ip net.IP
+ iplen := 0
+ if path.Nlri.EvpnNlri.MacIpAdv.IpAddr != "0.0.0.0" {
+ ip = net.ParseIP(path.Nlri.EvpnNlri.MacIpAdv.IpAddr)
+ if ip == nil {
+ result.ResponseErr = fmt.Errorf("Invalid ip prefix: %s", path.Nlri.EvpnNlri.MacIpAdv.IpAddr)
+ goto ERR
+ }
+ iplen = net.IPv4len * 8
+ if ip.To4() == nil {
+ iplen = net.IPv6len * 8
+ }
+ }
+
+ var labels []uint32
+ if len(path.Nlri.EvpnNlri.MacIpAdv.Labels) == 0 {
+ labels = []uint32{0}
+ } else {
+ labels = path.Nlri.EvpnNlri.MacIpAdv.Labels
+ }
+
+ eTag = path.Nlri.EvpnNlri.MacIpAdv.Etag
+ macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
+ RD: bgp.NewRouteDistinguisherIPAddressAS(routerId.String(), 0),
+ ESI: bgp.EthernetSegmentIdentifier{
+ Type: bgp.ESI_ARBITRARY,
+ },
+ MacAddressLength: 48,
+ MacAddress: mac,
+ IPAddressLength: uint8(iplen),
+ IPAddress: ip,
+ Labels: labels,
+ ETag: eTag,
+ }
+ nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
+ case bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG:
+ eTag = path.Nlri.EvpnNlri.MulticastEtag.Etag
+ ip := peerInfo.LocalID
+ iplen := net.IPv4len * 8
+ if ip.To4() == nil {
+ iplen = net.IPv6len * 8
+ }
+ multicastEtag := &bgp.EVPNMulticastEthernetTagRoute{
+ RD: bgp.NewRouteDistinguisherIPAddressAS(routerId.String(), 0),
+ IPAddressLength: uint8(iplen),
+ IPAddress: ip,
+ ETag: eTag,
+ }
+ nlri = bgp.NewEVPNNLRI(bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG, 0, multicastEtag)
}
- nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri}))
+ isTransitive := true
+ rt := bgp.NewTwoOctetAsSpecificExtended(asn, eTag, isTransitive)
+ encap := &bgp.OpaqueExtended{isTransitive, &bgp.EncapExtended{bgp.TUNNEL_TYPE_VXLAN}}
+ pattr = append(pattr, bgp.NewPathAttributeExtendedCommunities([]bgp.ExtendedCommunityInterface{rt, encap}))
case bgp.RF_ENCAP:
endpoint := net.ParseIP(path.Nlri.Prefix)
if endpoint == nil {
result.ResponseErr = fmt.Errorf("Invalid endpoint ip address: %s", path.Nlri.Prefix)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
+ goto ERR
}
nlri = bgp.NewEncapNLRI(endpoint.String())
@@ -820,9 +849,7 @@ func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*t
}
default:
result.ResponseErr = fmt.Errorf("Invalid endpoint ip address: %s", path.Nlri.Prefix)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
+ goto ERR
}
nlri = bgp.NewRouteTargetMembershipNLRI(peerInfo.AS, ec)
@@ -831,13 +858,16 @@ func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*t
default:
result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return pathList
+ goto ERR
}
- p := table.NewPath(peerInfo, nlri, isWithdraw, pattr, false, time.Now())
+ p = table.NewPath(peerInfo, nlri, isWithdraw, pattr, false, time.Now())
return []*table.Path{p}
+ERR:
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return []*table.Path{}
+
}
func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {