diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-08-03 14:04:34 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-03 21:59:39 +0900 |
commit | 84dd9d6983564b37b7e146264c44da6874a08cf4 (patch) | |
tree | 1dcda7f9b8164aec87c0fc6c889f8499c6fd8492 /server/server.go | |
parent | d895c87c741084b4469bb260e3ef94f7793a8f92 (diff) |
api: use serialized buffer rather than protobuf struct to add paths
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server/server.go')
-rw-r--r-- | server/server.go | 228 |
1 files changed, 27 insertions, 201 deletions
diff --git a/server/server.go b/server/server.go index b2ad3764..8eca9d75 100644 --- a/server/server.go +++ b/server/server.go @@ -737,15 +737,12 @@ func (server *BgpServer) checkNeighborRequest(grpcReq *GrpcRequest) (*Peer, erro func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*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)) - rf := grpcReq.RouteFamily - path, ok := grpcReq.Data.(*api.Path) + args, ok := grpcReq.Data.(*api.ModPathArguments) if !ok { result.ResponseErr = fmt.Errorf("type assertion failed") goto ERR @@ -754,219 +751,48 @@ func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []*t isWithdraw = true } - 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) + if len(args.RawNlri) > 0 { + nlri = &bgp.NLRInfo{} + err := nlri.DecodeFromBytes(args.RawNlri) + if err != nil { + result.ResponseErr = err goto ERR } - ones, _ := net.Mask.Size() - nlri = &bgp.NLRInfo{ - IPAddrPrefix: *bgp.NewIPAddrPrefix(uint8(ones), ip.String()), - } - - pattr = append(pattr, bgp.NewPathAttributeNextHop("0.0.0.0")) - - case bgp.RF_IPv6_UC: + } - ip, net, _ := net.ParseCIDR(path.Nlri.Prefix) - if ip.To16() == nil { - result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", path.Nlri.Prefix) + for _, attr := range args.RawPattrs { + p, err := bgp.GetPathAttribute(attr) + if err != nil { + result.ResponseErr = err goto ERR } - ones, _ := net.Mask.Size() - nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String()) - - pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri})) - - case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN: - var rd bgp.RouteDistinguisherInterface - switch path.Nlri.VpnNlri.Rd.Type { - case api.ROUTE_DISTINGUISHER_TYPE_TWO_OCTET_AS: - a, err := strconv.Atoi(path.Nlri.VpnNlri.Rd.Admin) - if err != nil { - result.ResponseErr = fmt.Errorf("Invalid admin value: %s", path.Nlri.VpnNlri.Rd.Admin) - goto ERR - } - rd = bgp.NewRouteDistinguisherTwoOctetAS(uint16(a), path.Nlri.VpnNlri.Rd.Assigned) - case api.ROUTE_DISTINGUISHER_TYPE_IP4: - ip := net.ParseIP(path.Nlri.VpnNlri.Rd.Admin) - if ip.To4() == nil { - result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", path.Nlri.VpnNlri.Rd.Admin) - goto ERR - } - assigned := uint16(path.Nlri.VpnNlri.Rd.Assigned) - rd = bgp.NewRouteDistinguisherIPAddressAS(path.Nlri.VpnNlri.Rd.Admin, assigned) - case api.ROUTE_DISTINGUISHER_TYPE_FOUR_OCTET_AS: - a, err := strconv.Atoi(path.Nlri.VpnNlri.Rd.Admin) - if err != nil { - result.ResponseErr = fmt.Errorf("Invalid admin value: %s", path.Nlri.VpnNlri.Rd.Admin) - goto ERR - } - admin := uint32(a) - assigned := uint16(path.Nlri.VpnNlri.Rd.Assigned) - rd = bgp.NewRouteDistinguisherFourOctetAS(admin, assigned) - } - - mpls := bgp.NewMPLSLabelStack(0) - if rf == bgp.RF_IPv4_VPN { - nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(path.Nlri.VpnNlri.IpAddrLen), path.Nlri.VpnNlri.IpAddr, *mpls, rd) - pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri})) - } else { - nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(path.Nlri.VpnNlri.IpAddrLen), path.Nlri.VpnNlri.IpAddr, *mpls, rd) - pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri})) - } - - case bgp.RF_EVPN: - 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 - - 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) - } - 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) + err = p.DecodeFromBytes(attr) + if err != nil { + result.ResponseErr = err goto ERR - } - nlri = bgp.NewEncapNLRI(endpoint.String()) - pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri})) - iterSubTlvs := func(subTlvs []*api.TunnelEncapSubTLV) { - for _, subTlv := range subTlvs { - if subTlv.Type == api.ENCAP_SUBTLV_TYPE_COLOR { - color := subTlv.Color - subTlv := &bgp.TunnelEncapSubTLV{ - Type: bgp.ENCAP_SUBTLV_TYPE_COLOR, - Value: &bgp.TunnelEncapSubTLVColor{color}, - } - tlv := &bgp.TunnelEncapTLV{ - Type: bgp.TUNNEL_TYPE_VXLAN, - Value: []*bgp.TunnelEncapSubTLV{subTlv}, - } - attr := bgp.NewPathAttributeTunnelEncap([]*bgp.TunnelEncapTLV{tlv}) - pattr = append(pattr, attr) - break - } - } - } - - iterTlvs := func(tlvs []*api.TunnelEncapTLV) { - for _, tlv := range tlvs { - if tlv.Type == api.TUNNEL_TYPE_VXLAN { - iterSubTlvs(tlv.SubTlv) - break - } - } - } - - func(attrs []*api.PathAttr) { - for _, attr := range attrs { - if attr.Type == api.BGP_ATTR_TYPE_TUNNEL_ENCAP { - iterTlvs(attr.TunnelEncap) - break - } - } - }(path.Attrs) - - case bgp.RF_RTC_UC: - var ec bgp.ExtendedCommunityInterface - target := path.Nlri.RtNlri.Target - ec_type := target.Type - ec_subtype := target.Subtype - switch ec_type { - case api.EXTENDED_COMMUNITIE_TYPE_TWO_OCTET_AS_SPECIFIC: - if target.Asn == 0 && target.LocalAdmin == 0 { - break - } - ec = &bgp.TwoOctetAsSpecificExtended{ - SubType: bgp.ExtendedCommunityAttrSubType(ec_subtype), - AS: uint16(target.Asn), - LocalAdmin: target.LocalAdmin, - IsTransitive: true, + switch p.GetType() { + case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: + value := p.(*bgp.PathAttributeMpReachNLRI).Value + if len(value) != 1 { + result.ResponseErr = fmt.Errorf("include only one route in mp_reach_nlri") + goto ERR } + nlri = p.(*bgp.PathAttributeMpReachNLRI).Value[0] + fallthrough default: - result.ResponseErr = fmt.Errorf("Invalid endpoint ip address: %s", path.Nlri.Prefix) - goto ERR + pattr = append(pattr, p) } + } - nlri = bgp.NewRouteTargetMembershipNLRI(peerInfo.AS, ec) - - pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri})) - - default: - result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf) + if nlri == nil { + result.ResponseErr = fmt.Errorf("no nlri included") goto ERR } - p = table.NewPath(peerInfo, nlri, isWithdraw, pattr, false, time.Now()) - return []*table.Path{p} + return []*table.Path{table.NewPath(peerInfo, nlri, isWithdraw, pattr, false, time.Now())} ERR: grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) |