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  }