github.com/osrg/gobgp@v2.0.0+incompatible/internal/pkg/apiutil/util.go (about) 1 // Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package apiutil 17 18 import ( 19 "encoding/json" 20 "net" 21 "time" 22 23 "github.com/golang/protobuf/ptypes" 24 api "github.com/osrg/gobgp/api" 25 "github.com/osrg/gobgp/pkg/packet/bgp" 26 ) 27 28 // workaround. This for the json format compatibility. Once we update senario tests, we can remove this. 29 type Path struct { 30 Nlri bgp.AddrPrefixInterface `json:"nlri"` 31 Age int64 `json:"age"` 32 Best bool `json:"best"` 33 Attrs []bgp.PathAttributeInterface `json:"attrs"` 34 Stale bool `json:"stale"` 35 Withdrawal bool `json:"withdrawal,omitempty"` 36 SourceID net.IP `json:"source-id,omitempty"` 37 NeighborIP net.IP `json:"neighbor-ip,omitempty"` 38 } 39 40 type Destination struct { 41 Paths []*Path 42 } 43 44 func (d *Destination) MarshalJSON() ([]byte, error) { 45 return json.Marshal(d.Paths) 46 } 47 48 func NewDestination(dst *api.Destination) *Destination { 49 l := make([]*Path, 0, len(dst.Paths)) 50 for _, p := range dst.Paths { 51 nlri, _ := GetNativeNlri(p) 52 attrs, _ := GetNativePathAttributes(p) 53 t, _ := ptypes.Timestamp(p.Age) 54 l = append(l, &Path{ 55 Nlri: nlri, 56 Age: t.Unix(), 57 Best: p.Best, 58 Attrs: attrs, 59 Stale: p.Stale, 60 Withdrawal: p.IsWithdraw, 61 SourceID: net.ParseIP(p.SourceId), 62 NeighborIP: net.ParseIP(p.NeighborIp), 63 }) 64 } 65 return &Destination{Paths: l} 66 } 67 68 func NewPath(nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, age time.Time) *api.Path { 69 t, _ := ptypes.TimestampProto(age) 70 return &api.Path{ 71 Nlri: MarshalNLRI(nlri), 72 Pattrs: MarshalPathAttributes(attrs), 73 Age: t, 74 IsWithdraw: isWithdraw, 75 Family: ToApiFamily(nlri.AFI(), nlri.SAFI()), 76 Identifier: nlri.PathIdentifier(), 77 } 78 } 79 80 func getNLRI(family bgp.RouteFamily, buf []byte) (bgp.AddrPrefixInterface, error) { 81 afi, safi := bgp.RouteFamilyToAfiSafi(family) 82 nlri, err := bgp.NewPrefixFromRouteFamily(afi, safi) 83 if err != nil { 84 return nil, err 85 } 86 if err := nlri.DecodeFromBytes(buf); err != nil { 87 return nil, err 88 } 89 return nlri, nil 90 } 91 92 func GetNativeNlri(p *api.Path) (bgp.AddrPrefixInterface, error) { 93 if len(p.NlriBinary) > 0 { 94 return getNLRI(ToRouteFamily(p.Family), p.NlriBinary) 95 } 96 return UnmarshalNLRI(ToRouteFamily(p.Family), p.Nlri) 97 } 98 99 func GetNativePathAttributes(p *api.Path) ([]bgp.PathAttributeInterface, error) { 100 pattrsLen := len(p.PattrsBinary) 101 if pattrsLen > 0 { 102 pattrs := make([]bgp.PathAttributeInterface, 0, pattrsLen) 103 for _, attr := range p.PattrsBinary { 104 a, err := bgp.GetPathAttribute(attr) 105 if err != nil { 106 return nil, err 107 } 108 err = a.DecodeFromBytes(attr) 109 if err != nil { 110 return nil, err 111 } 112 pattrs = append(pattrs, a) 113 } 114 return pattrs, nil 115 } 116 return UnmarshalPathAttributes(p.Pattrs) 117 } 118 119 func ToRouteFamily(f *api.Family) bgp.RouteFamily { 120 return bgp.AfiSafiToRouteFamily(uint16(f.Afi), uint8(f.Safi)) 121 } 122 123 func ToApiFamily(afi uint16, safi uint8) *api.Family { 124 return &api.Family{ 125 Afi: api.Family_Afi(afi), 126 Safi: api.Family_Safi(safi), 127 } 128 }