diff options
-rw-r--r-- | api/capability.go | 287 | ||||
-rw-r--r-- | api/capability_test.go | 215 | ||||
-rw-r--r-- | cmd/gobgp/cmd/global.go | 3 | ||||
-rw-r--r-- | cmd/gobgp/cmd/global_test.go | 3 | ||||
-rw-r--r-- | cmd/gobgp/cmd/monitor.go | 7 | ||||
-rw-r--r-- | cmd/gobgp/cmd/mrt.go | 3 | ||||
-rw-r--r-- | cmd/gobgp/cmd/neighbor.go | 13 | ||||
-rw-r--r-- | cmd/gobgp/cmd/vrf.go | 6 | ||||
-rw-r--r-- | cmd/gobgp/lib/path.go | 5 | ||||
-rw-r--r-- | cmd/gobgpd/main.go | 5 | ||||
-rw-r--r-- | internal/pkg/apiutil/attribute.go (renamed from api/attribute.go) | 841 | ||||
-rw-r--r-- | internal/pkg/apiutil/attribute_test.go (renamed from api/attribute_test.go) | 502 | ||||
-rw-r--r-- | internal/pkg/apiutil/capability.go | 244 | ||||
-rw-r--r-- | internal/pkg/apiutil/capability_test.go | 251 | ||||
-rw-r--r-- | internal/pkg/apiutil/util.go (renamed from api/util.go) | 83 | ||||
-rw-r--r-- | internal/pkg/client/client.go | 11 | ||||
-rw-r--r-- | pkg/server/grpc_server.go | 29 |
17 files changed, 1281 insertions, 1227 deletions
diff --git a/api/capability.go b/api/capability.go deleted file mode 100644 index 15231bbb..00000000 --- a/api/capability.go +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gobgpapi - -import ( - "fmt" - - proto "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" - "github.com/golang/protobuf/ptypes/any" - "github.com/osrg/gobgp/pkg/packet/bgp" -) - -func NewMultiProtocolCapability(a *bgp.CapMultiProtocol) *MultiProtocolCapability { - return &MultiProtocolCapability{ - Family: Family(a.CapValue), - } -} - -func (a *MultiProtocolCapability) ToNative() (*bgp.CapMultiProtocol, error) { - return bgp.NewCapMultiProtocol(bgp.RouteFamily(a.Family)), nil -} - -func NewRouteRefreshCapability(a *bgp.CapRouteRefresh) *RouteRefreshCapability { - return &RouteRefreshCapability{} -} - -func (a *RouteRefreshCapability) ToNative() (*bgp.CapRouteRefresh, error) { - return bgp.NewCapRouteRefresh(), nil -} - -func NewCarryingLabelInfoCapability(a *bgp.CapCarryingLabelInfo) *CarryingLabelInfoCapability { - return &CarryingLabelInfoCapability{} -} - -func (a *CarryingLabelInfoCapability) ToNative() (*bgp.CapCarryingLabelInfo, error) { - return bgp.NewCapCarryingLabelInfo(), nil -} - -func NewExtendedNexthopCapability(a *bgp.CapExtendedNexthop) *ExtendedNexthopCapability { - tuples := make([]*ExtendedNexthopCapabilityTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - tuples = append(tuples, &ExtendedNexthopCapabilityTuple{ - NlriFamily: Family(bgp.AfiSafiToRouteFamily(t.NLRIAFI, uint8(t.NLRISAFI))), - NexthopFamily: Family(bgp.AfiSafiToRouteFamily(t.NexthopAFI, bgp.SAFI_UNICAST)), - }) - } - return &ExtendedNexthopCapability{ - Tuples: tuples, - } -} - -func (a *ExtendedNexthopCapability) ToNative() (*bgp.CapExtendedNexthop, error) { - tuples := make([]*bgp.CapExtendedNexthopTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - var nhAfi uint16 - switch t.NexthopFamily { - case Family_IPv4: - nhAfi = bgp.AFI_IP - case Family_IPv6: - nhAfi = bgp.AFI_IP6 - default: - return nil, fmt.Errorf("invalid address family for nexthop afi in extended nexthop capability: %s", t.NexthopFamily) - } - tuples = append(tuples, bgp.NewCapExtendedNexthopTuple(bgp.RouteFamily(t.NlriFamily), nhAfi)) - } - return bgp.NewCapExtendedNexthop(tuples), nil -} - -func NewGracefulRestartCapability(a *bgp.CapGracefulRestart) *GracefulRestartCapability { - tuples := make([]*GracefulRestartCapabilityTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - tuples = append(tuples, &GracefulRestartCapabilityTuple{ - Family: Family(bgp.AfiSafiToRouteFamily(t.AFI, uint8(t.SAFI))), - Flags: uint32(t.Flags), - }) - } - return &GracefulRestartCapability{ - Flags: uint32(a.Flags), - Time: uint32(a.Time), - Tuples: tuples, - } -} - -func (a *GracefulRestartCapability) ToNative() (*bgp.CapGracefulRestart, error) { - tuples := make([]*bgp.CapGracefulRestartTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - var forward bool - if t.Flags&0x80 > 0 { - forward = true - } - tuples = append(tuples, bgp.NewCapGracefulRestartTuple(bgp.RouteFamily(t.Family), forward)) - } - var restarting bool - if a.Flags&0x08 > 0 { - restarting = true - } - var notification bool - if a.Flags&0x04 > 0 { - notification = true - } - return bgp.NewCapGracefulRestart(restarting, notification, uint16(a.Time), tuples), nil -} - -func NewFourOctetASNumberCapability(a *bgp.CapFourOctetASNumber) *FourOctetASNumberCapability { - return &FourOctetASNumberCapability{ - As: a.CapValue, - } -} - -func (a *FourOctetASNumberCapability) ToNative() (*bgp.CapFourOctetASNumber, error) { - return bgp.NewCapFourOctetASNumber(a.As), nil -} - -func NewAddPathCapability(a *bgp.CapAddPath) *AddPathCapability { - tuples := make([]*AddPathCapabilityTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - tuples = append(tuples, &AddPathCapabilityTuple{ - Family: Family(t.RouteFamily), - Mode: AddPathMode(t.Mode), - }) - } - return &AddPathCapability{ - Tuples: tuples, - } -} - -func (a *AddPathCapability) ToNative() (*bgp.CapAddPath, error) { - tuples := make([]*bgp.CapAddPathTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - tuples = append(tuples, bgp.NewCapAddPathTuple(bgp.RouteFamily(t.Family), bgp.BGPAddPathMode(t.Mode))) - } - return bgp.NewCapAddPath(tuples), nil -} - -func NewEnhancedRouteRefreshCapability(a *bgp.CapEnhancedRouteRefresh) *EnhancedRouteRefreshCapability { - return &EnhancedRouteRefreshCapability{} -} - -func (a *EnhancedRouteRefreshCapability) ToNative() (*bgp.CapEnhancedRouteRefresh, error) { - return bgp.NewCapEnhancedRouteRefresh(), nil -} - -func NewLongLivedGracefulRestartCapability(a *bgp.CapLongLivedGracefulRestart) *LongLivedGracefulRestartCapability { - tuples := make([]*LongLivedGracefulRestartCapabilityTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - tuples = append(tuples, &LongLivedGracefulRestartCapabilityTuple{ - Family: Family(bgp.AfiSafiToRouteFamily(t.AFI, uint8(t.SAFI))), - Flags: uint32(t.Flags), - Time: t.RestartTime, - }) - } - return &LongLivedGracefulRestartCapability{ - Tuples: tuples, - } -} - -func (a *LongLivedGracefulRestartCapability) ToNative() (*bgp.CapLongLivedGracefulRestart, error) { - tuples := make([]*bgp.CapLongLivedGracefulRestartTuple, 0, len(a.Tuples)) - for _, t := range a.Tuples { - var forward bool - if t.Flags&0x80 > 0 { - forward = true - } - tuples = append(tuples, bgp.NewCapLongLivedGracefulRestartTuple(bgp.RouteFamily(t.Family), forward, t.Time)) - } - return bgp.NewCapLongLivedGracefulRestart(tuples), nil -} - -func NewRouteRefreshCiscoCapability(a *bgp.CapRouteRefreshCisco) *RouteRefreshCiscoCapability { - return &RouteRefreshCiscoCapability{} -} - -func (a *RouteRefreshCiscoCapability) ToNative() (*bgp.CapRouteRefreshCisco, error) { - return bgp.NewCapRouteRefreshCisco(), nil -} - -func NewUnknownCapability(a *bgp.CapUnknown) *UnknownCapability { - return &UnknownCapability{ - Code: uint32(a.CapCode), - Value: a.CapValue, - } -} - -func (a *UnknownCapability) ToNative() (*bgp.CapUnknown, error) { - return bgp.NewCapUnknown(bgp.BGPCapabilityCode(a.Code), a.Value), nil -} - -func MarshalCapability(value bgp.ParameterCapabilityInterface) (*any.Any, error) { - var m proto.Message - switch n := value.(type) { - case *bgp.CapMultiProtocol: - m = NewMultiProtocolCapability(n) - case *bgp.CapRouteRefresh: - m = NewRouteRefreshCapability(n) - case *bgp.CapCarryingLabelInfo: - m = NewCarryingLabelInfoCapability(n) - case *bgp.CapExtendedNexthop: - m = NewExtendedNexthopCapability(n) - case *bgp.CapGracefulRestart: - m = NewGracefulRestartCapability(n) - case *bgp.CapFourOctetASNumber: - m = NewFourOctetASNumberCapability(n) - case *bgp.CapAddPath: - m = NewAddPathCapability(n) - case *bgp.CapEnhancedRouteRefresh: - m = NewEnhancedRouteRefreshCapability(n) - case *bgp.CapLongLivedGracefulRestart: - m = NewLongLivedGracefulRestartCapability(n) - case *bgp.CapRouteRefreshCisco: - m = NewRouteRefreshCiscoCapability(n) - case *bgp.CapUnknown: - m = NewUnknownCapability(n) - default: - return nil, fmt.Errorf("invalid capability type to marshal: %+v", value) - } - return ptypes.MarshalAny(m) -} - -func MarshalCapabilities(values []bgp.ParameterCapabilityInterface) ([]*any.Any, error) { - caps := make([]*any.Any, 0, len(values)) - for _, value := range values { - a, err := MarshalCapability(value) - if err != nil { - return nil, err - } - caps = append(caps, a) - } - return caps, nil -} - -func UnmarshalCapability(a *any.Any) (bgp.ParameterCapabilityInterface, error) { - var value ptypes.DynamicAny - if err := ptypes.UnmarshalAny(a, &value); err != nil { - return nil, fmt.Errorf("failed to unmarshal capability: %s", err) - } - switch v := value.Message.(type) { - case *MultiProtocolCapability: - return v.ToNative() - case *RouteRefreshCapability: - return v.ToNative() - case *CarryingLabelInfoCapability: - return v.ToNative() - case *ExtendedNexthopCapability: - return v.ToNative() - case *GracefulRestartCapability: - return v.ToNative() - case *FourOctetASNumberCapability: - return v.ToNative() - case *AddPathCapability: - return v.ToNative() - case *EnhancedRouteRefreshCapability: - return v.ToNative() - case *LongLivedGracefulRestartCapability: - return v.ToNative() - case *RouteRefreshCiscoCapability: - return v.ToNative() - case *UnknownCapability: - return v.ToNative() - } - return nil, fmt.Errorf("invalid capability type to unmarshal: %s", a.TypeUrl) -} - -func UnmarshalCapabilities(values []*any.Any) ([]bgp.ParameterCapabilityInterface, error) { - caps := make([]bgp.ParameterCapabilityInterface, 0, len(values)) - for _, value := range values { - c, err := UnmarshalCapability(value) - if err != nil { - return nil, err - } - caps = append(caps, c) - } - return caps, nil -} diff --git a/api/capability_test.go b/api/capability_test.go deleted file mode 100644 index a0c34db1..00000000 --- a/api/capability_test.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gobgpapi - -import ( - "testing" - - "github.com/osrg/gobgp/pkg/packet/bgp" - "github.com/stretchr/testify/assert" -) - -func Test_MultiProtocolCapability(t *testing.T) { - assert := assert.New(t) - - input := &MultiProtocolCapability{ - Family: Family_IPv4, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(bgp.RF_IPv4_UC, n.CapValue) - - output := NewMultiProtocolCapability(n) - assert.Equal(input, output) -} - -func Test_RouteRefreshCapability(t *testing.T) { - assert := assert.New(t) - - input := &RouteRefreshCapability{} - - n, err := input.ToNative() - assert.Nil(err) - - output := NewRouteRefreshCapability(n) - assert.Equal(input, output) -} - -func Test_CarryingLabelInfoCapability(t *testing.T) { - assert := assert.New(t) - - input := &CarryingLabelInfoCapability{} - - n, err := input.ToNative() - assert.Nil(err) - - output := NewCarryingLabelInfoCapability(n) - assert.Equal(input, output) -} - -func Test_ExtendedNexthopCapability(t *testing.T) { - assert := assert.New(t) - - input := &ExtendedNexthopCapability{ - Tuples: []*ExtendedNexthopCapabilityTuple{ - { - NlriFamily: Family_IPv4, - NexthopFamily: Family_IPv6, - }, - }, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(1, len(n.Tuples)) - assert.Equal(uint16(bgp.AFI_IP), n.Tuples[0].NLRIAFI) - assert.Equal(uint16(bgp.SAFI_UNICAST), n.Tuples[0].NLRISAFI) - assert.Equal(uint16(bgp.AFI_IP6), n.Tuples[0].NexthopAFI) - - output := NewExtendedNexthopCapability(n) - assert.Equal(input, output) -} - -func Test_GracefulRestartCapability(t *testing.T) { - assert := assert.New(t) - - input := &GracefulRestartCapability{ - Flags: 0x08 | 0x04, // restarting|notification - Time: 90, - Tuples: []*GracefulRestartCapabilityTuple{ - { - Family: Family_IPv4, - Flags: 0x80, // forward - }, - }, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(1, len(n.Tuples)) - assert.Equal(uint8(0x08|0x04), n.Flags) - assert.Equal(uint16(90), n.Time) - assert.Equal(uint16(bgp.AFI_IP), n.Tuples[0].AFI) - assert.Equal(uint8(bgp.SAFI_UNICAST), n.Tuples[0].SAFI) - assert.Equal(uint8(0x80), n.Tuples[0].Flags) - - output := NewGracefulRestartCapability(n) - assert.Equal(input, output) -} - -func Test_FourOctetASNumberCapability(t *testing.T) { - assert := assert.New(t) - - input := &FourOctetASNumberCapability{ - As: 100, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(uint32(100), n.CapValue) - - output := NewFourOctetASNumberCapability(n) - assert.Equal(input, output) -} - -func Test_AddPathCapability(t *testing.T) { - assert := assert.New(t) - - input := &AddPathCapability{ - Tuples: []*AddPathCapabilityTuple{ - { - Family: Family_IPv4, - Mode: AddPathMode_MODE_BOTH, - }, - }, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(1, len(n.Tuples)) - assert.Equal(bgp.RF_IPv4_UC, n.Tuples[0].RouteFamily) - assert.Equal(bgp.BGP_ADD_PATH_BOTH, n.Tuples[0].Mode) - - output := NewAddPathCapability(n) - assert.Equal(input, output) -} - -func Test_EnhancedRouteRefreshCapability(t *testing.T) { - assert := assert.New(t) - - input := &EnhancedRouteRefreshCapability{} - - n, err := input.ToNative() - assert.Nil(err) - - output := NewEnhancedRouteRefreshCapability(n) - assert.Equal(input, output) -} - -func Test_LongLivedGracefulRestartCapability(t *testing.T) { - assert := assert.New(t) - - input := &LongLivedGracefulRestartCapability{ - Tuples: []*LongLivedGracefulRestartCapabilityTuple{ - { - Family: Family_IPv4, - Flags: 0x80, // forward - Time: 90, - }, - }, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(1, len(n.Tuples)) - assert.Equal(uint16(bgp.AFI_IP), n.Tuples[0].AFI) - assert.Equal(uint8(bgp.SAFI_UNICAST), n.Tuples[0].SAFI) - assert.Equal(uint8(0x80), n.Tuples[0].Flags) - assert.Equal(uint32(90), n.Tuples[0].RestartTime) - - output := NewLongLivedGracefulRestartCapability(n) - assert.Equal(input, output) -} - -func Test_RouteRefreshCiscoCapability(t *testing.T) { - assert := assert.New(t) - - input := &RouteRefreshCiscoCapability{} - - n, err := input.ToNative() - assert.Nil(err) - - output := NewRouteRefreshCiscoCapability(n) - assert.Equal(input, output) -} - -func Test_UnknownCapability(t *testing.T) { - assert := assert.New(t) - - input := &UnknownCapability{ - Code: 0xff, - Value: []byte{0x11, 0x22, 0x33, 0x44}, - } - - n, err := input.ToNative() - assert.Nil(err) - assert.Equal(bgp.BGPCapabilityCode(0xff), n.CapCode) - assert.Equal([]byte{0x11, 0x22, 0x33, 0x44}, n.CapValue) - - output := NewUnknownCapability(n) - assert.Equal(input, output) -} diff --git a/cmd/gobgp/cmd/global.go b/cmd/gobgp/cmd/global.go index 4559f4ac..b71deba9 100644 --- a/cmd/gobgp/cmd/global.go +++ b/cmd/gobgp/cmd/global.go @@ -28,6 +28,7 @@ import ( "github.com/spf13/cobra" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/internal/pkg/config" "github.com/osrg/gobgp/internal/pkg/table" @@ -1265,7 +1266,7 @@ func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) { } sort.Slice(attrs, func(i, j int) bool { return attrs[i].GetType() < attrs[j].GetType() }) - return api.NewPath(nlri, false, attrs, time.Now()), nil + return apiutil.NewPath(nlri, false, attrs, time.Now()), nil } func showGlobalRib(args []string) error { diff --git a/cmd/gobgp/cmd/global_test.go b/cmd/gobgp/cmd/global_test.go index 7aecb904..c00db1df 100644 --- a/cmd/gobgp/cmd/global_test.go +++ b/cmd/gobgp/cmd/global_test.go @@ -19,6 +19,7 @@ import ( "strings" "testing" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/pkg/packet/bgp" "github.com/stretchr/testify/assert" ) @@ -30,7 +31,7 @@ func Test_ParsePath(t *testing.T) { path, err := ParsePath(bgp.RF_IPv4_UC, strings.Split(buf, " ")) assert.Nil(err) i := 0 - attrs, _ := path.GetNativePathAttributes() + attrs, _ := apiutil.GetNativePathAttributes(path) for _, a := range attrs { assert.True(i < int(a.GetType())) i = int(a.GetType()) diff --git a/cmd/gobgp/cmd/monitor.go b/cmd/gobgp/cmd/monitor.go index 6b07eb2d..9055ecf5 100644 --- a/cmd/gobgp/cmd/monitor.go +++ b/cmd/gobgp/cmd/monitor.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/pkg/packet/bgp" ) @@ -39,13 +40,13 @@ func makeMonitorRouteArgs(p *api.Path, showIdentifier bgp.BGPAddPathMode) []inte // NLRI // If Add-Path required, append Path Identifier. - nlri, _ := p.GetNativeNlri() + nlri, _ := apiutil.GetNativeNlri(p) if showIdentifier != bgp.BGP_ADD_PATH_NONE { pathStr = append(pathStr, p.GetIdentifier()) } pathStr = append(pathStr, nlri) - attrs, _ := p.GetNativePathAttributes() + attrs, _ := apiutil.GetNativePathAttributes(p) // Next Hop nexthop := "fictitious" if n := getNextHopFromPathAttributes(attrs); n != nil { @@ -102,7 +103,7 @@ func NewMonitorCmd() *cobra.Command { exitWithError(err) } if globalOpts.Json { - j, _ := json.Marshal(dst.Paths) + j, _ := json.Marshal(apiutil.NewDestination(dst)) fmt.Println(string(j)) } else { monitorRoute(dst.Paths, showIdentifier) diff --git a/cmd/gobgp/cmd/mrt.go b/cmd/gobgp/cmd/mrt.go index 32c4fc9b..58b4381d 100644 --- a/cmd/gobgp/cmd/mrt.go +++ b/cmd/gobgp/cmd/mrt.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/cobra" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/pkg/packet/bgp" "github.com/osrg/gobgp/pkg/packet/mrt" ) @@ -143,7 +144,7 @@ func injectMrt() error { } } - path := api.NewPath(nlri, false, attrs, time.Unix(int64(e.OriginatedTime), 0)) + path := apiutil.NewPath(nlri, false, attrs, time.Unix(int64(e.OriginatedTime), 0)) path.SourceAsn = peers[e.PeerIndex].AS path.SourceId = peers[e.PeerIndex].BgpId.String() diff --git a/cmd/gobgp/cmd/neighbor.go b/cmd/gobgp/cmd/neighbor.go index c6dd8be6..ad946e5b 100644 --- a/cmd/gobgp/cmd/neighbor.go +++ b/cmd/gobgp/cmd/neighbor.go @@ -28,6 +28,7 @@ import ( "github.com/spf13/cobra" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/internal/pkg/config" "github.com/osrg/gobgp/pkg/packet/bgp" ) @@ -478,7 +479,7 @@ func getPathAttributeString(nlri bgp.AddrPrefixInterface, attrs []bgp.PathAttrib } func makeShowRouteArgs(p *api.Path, idx int, now time.Time, showAge, showBest, showLabel bool, showIdentifier bgp.BGPAddPathMode) []interface{} { - nlri, _ := p.GetNativeNlri() + nlri, _ := apiutil.GetNativeNlri(p) // Path Symbols (e.g. "*>") args := []interface{}{getPathSymbolString(p, idx, showBest)} @@ -501,7 +502,7 @@ func makeShowRouteArgs(p *api.Path, idx int, now time.Time, showAge, showBest, s args = append(args, label) } - attrs, _ := p.GetNativePathAttributes() + attrs, _ := apiutil.GetNativePathAttributes(p) // Next Hop nexthop := "fictitious" if n := getNextHopFromPathAttributes(attrs); n != nil { @@ -591,14 +592,14 @@ func checkOriginAsWasNotShown(p *api.Path, asPath []bgp.AsPathParamInterface, sh func showValidationInfo(p *api.Path, shownAs map[uint32]struct{}) error { var asPath []bgp.AsPathParamInterface - attrs, _ := p.GetNativePathAttributes() + attrs, _ := apiutil.GetNativePathAttributes(p) for _, attr := range attrs { if attr.GetType() == bgp.BGP_ATTR_TYPE_AS_PATH { asPath = attr.(*bgp.PathAttributeAsPath).Value } } - nlri, _ := p.GetNativeNlri() + nlri, _ := apiutil.GetNativeNlri(p) if len(asPath) == 0 { return fmt.Errorf("The path to %s was locally generated.\n", nlri.String()) } else if !checkOriginAsWasNotShown(p, asPath, shownAs) { @@ -802,9 +803,9 @@ func showNeighborRib(r string, name string, args []string) error { } if globalOpts.Json { - d := make(map[string]*api.Destination) + d := make(map[string]*apiutil.Destination) for _, dst := range rib.GetDestinations() { - d[dst.Prefix] = dst + d[dst.Prefix] = apiutil.NewDestination(dst) } j, _ := json.Marshal(d) fmt.Println(string(j)) diff --git a/cmd/gobgp/cmd/vrf.go b/cmd/gobgp/cmd/vrf.go index fd55dc0a..a8c2fcd8 100644 --- a/cmd/gobgp/cmd/vrf.go +++ b/cmd/gobgp/cmd/vrf.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/pkg/packet/bgp" "github.com/golang/protobuf/ptypes/any" @@ -58,7 +58,7 @@ func showVrfs() error { lines := make([][]string, 0, len(vrfs)) for _, v := range vrfs { name := v.Name - rd, err := api.UnmarshalRD(v.Rd) + rd, err := apiutil.UnmarshalRD(v.Rd) if err != nil { return err } @@ -67,7 +67,7 @@ func showVrfs() error { f := func(rts []*any.Any) (string, error) { ret := make([]string, 0, len(rts)) for _, an := range rts { - rt, err := api.UnmarshalRT(an) + rt, err := apiutil.UnmarshalRT(an) if err != nil { return "", err } diff --git a/cmd/gobgp/lib/path.go b/cmd/gobgp/lib/path.go index 130f5444..8554b061 100644 --- a/cmd/gobgp/lib/path.go +++ b/cmd/gobgp/lib/path.go @@ -37,6 +37,7 @@ import ( "strings" "github.com/osrg/gobgp/cmd/gobgp/cmd" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/pkg/packet/bgp" ) @@ -57,14 +58,14 @@ func serialize_path(rf C.int, input *C.char) *C.path { return nil } path := C.new_path() - if nlri, err := p.GetNativeNlri(); err != nil { + if nlri, err := apiutil.GetNativeNlri(p); err != nil { return nil } else { buf, _ := nlri.Serialize() path.nlri.len = C.int(len(buf)) path.nlri.value = C.CString(string(buf)) } - attrs, err := p.GetNativePathAttributes() + attrs, err := apiutil.GetNativePathAttributes(p) if err != nil { return nil } diff --git a/cmd/gobgpd/main.go b/cmd/gobgpd/main.go index 6f1a364d..31af0f67 100644 --- a/cmd/gobgpd/main.go +++ b/cmd/gobgpd/main.go @@ -35,6 +35,7 @@ import ( "google.golang.org/grpc/credentials" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/internal/pkg/config" "github.com/osrg/gobgp/internal/pkg/table" "github.com/osrg/gobgp/pkg/packet/bgp" @@ -50,7 +51,7 @@ func marshalRouteTargets(l []string) ([]*any.Any, error) { if err != nil { return nil, err } - rtList = append(rtList, api.MarshalRT(rt)) + rtList = append(rtList, apiutil.MarshalRT(rt)) } return rtList, nil } @@ -252,7 +253,7 @@ func main() { if _, err := apiServer.AddVrf(context.Background(), &api.AddVrfRequest{ Vrf: &api.Vrf{ Name: vrf.Config.Name, - Rd: api.MarshalRD(rd), + Rd: apiutil.MarshalRD(rd), Id: uint32(vrf.Config.Id), ImportRt: importRtList, ExportRt: exportRtList, diff --git a/api/attribute.go b/internal/pkg/apiutil/attribute.go index c4ac1375..e149edbb 100644 --- a/api/attribute.go +++ b/internal/pkg/apiutil/attribute.go @@ -13,163 +13,155 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gobgpapi +package apiutil import ( + "errors" "fmt" "net" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" + api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/pkg/packet/bgp" log "github.com/sirupsen/logrus" ) -func NewOriginAttributeFromNative(a *bgp.PathAttributeOrigin) *OriginAttribute { - return &OriginAttribute{ - Origin: uint32(a.Value), +func UnmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) } + switch a := value.Message.(type) { + case *api.OriginAttribute: + return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil + case *api.AsPathAttribute: + params := make([]bgp.AsPathParamInterface, 0, len(a.Segments)) + for _, segment := range a.Segments { + params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) + } + return bgp.NewPathAttributeAsPath(params), nil + case *api.NextHopAttribute: + nexthop := net.ParseIP(a.NextHop).To4() + if nexthop == nil { + return nil, fmt.Errorf("invalid nexthop address: %s", a.NextHop) + } + return bgp.NewPathAttributeNextHop(a.NextHop), nil + case *api.MultiExitDiscAttribute: + return bgp.NewPathAttributeMultiExitDisc(a.Med), nil + case *api.LocalPrefAttribute: + return bgp.NewPathAttributeLocalPref(a.LocalPref), nil + case *api.AtomicAggregateAttribute: + return bgp.NewPathAttributeAtomicAggregate(), nil + case *api.AggregatorAttribute: + if net.ParseIP(a.Address).To4() == nil { + return nil, fmt.Errorf("invalid aggregator address: %s", a.Address) + } + return bgp.NewPathAttributeAggregator(a.As, a.Address), nil + case *api.CommunitiesAttribute: + return bgp.NewPathAttributeCommunities(a.Communities), nil + case *api.OriginatorIdAttribute: + if net.ParseIP(a.Id).To4() == nil { + return nil, fmt.Errorf("invalid originator id: %s", a.Id) + } + return bgp.NewPathAttributeOriginatorId(a.Id), nil + case *api.ClusterListAttribute: + for _, id := range a.Ids { + if net.ParseIP(id).To4() == nil { + return nil, fmt.Errorf("invalid cluster list: %s", a.Ids) + } + } + return bgp.NewPathAttributeClusterList(a.Ids), nil + } + return nil, errors.New("unexpected object") } -func (a *OriginAttribute) ToNative() (*bgp.PathAttributeOrigin, error) { - return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil +func NewOriginAttributeFromNative(a *bgp.PathAttributeOrigin) *api.OriginAttribute { + return &api.OriginAttribute{ + Origin: uint32(a.Value), + } } -func NewAsPathAttributeFromNative(a *bgp.PathAttributeAsPath) *AsPathAttribute { - segments := make([]*AsSegment, 0, len(a.Value)) +func NewAsPathAttributeFromNative(a *bgp.PathAttributeAsPath) *api.AsPathAttribute { + segments := make([]*api.AsSegment, 0, len(a.Value)) for _, param := range a.Value { - segments = append(segments, &AsSegment{ + segments = append(segments, &api.AsSegment{ Type: uint32(param.GetType()), Numbers: param.GetAS(), }) } - return &AsPathAttribute{ + return &api.AsPathAttribute{ Segments: segments, } } -func (a *AsPathAttribute) ToNative() (*bgp.PathAttributeAsPath, error) { - params := make([]bgp.AsPathParamInterface, 0, len(a.Segments)) - for _, segment := range a.Segments { - params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) - } - return bgp.NewPathAttributeAsPath(params), nil -} - -func NewNextHopAttributeFromNative(a *bgp.PathAttributeNextHop) *NextHopAttribute { - return &NextHopAttribute{ +func NewNextHopAttributeFromNative(a *bgp.PathAttributeNextHop) *api.NextHopAttribute { + return &api.NextHopAttribute{ NextHop: a.Value.String(), } } -func (a *NextHopAttribute) ToNative() (*bgp.PathAttributeNextHop, error) { - nexthop := net.ParseIP(a.NextHop).To4() - if nexthop == nil { - return nil, fmt.Errorf("invalid nexthop address: %s", a.NextHop) - } - return bgp.NewPathAttributeNextHop(a.NextHop), nil -} - -func NewMultiExitDiscAttributeFromNative(a *bgp.PathAttributeMultiExitDisc) *MultiExitDiscAttribute { - return &MultiExitDiscAttribute{ +func NewMultiExitDiscAttributeFromNative(a *bgp.PathAttributeMultiExitDisc) *api.MultiExitDiscAttribute { + return &api.MultiExitDiscAttribute{ Med: a.Value, } } -func (a *MultiExitDiscAttribute) ToNative() (*bgp.PathAttributeMultiExitDisc, error) { - return bgp.NewPathAttributeMultiExitDisc(a.Med), nil -} - -func NewLocalPrefAttributeFromNative(a *bgp.PathAttributeLocalPref) *LocalPrefAttribute { - return &LocalPrefAttribute{ +func NewLocalPrefAttributeFromNative(a *bgp.PathAttributeLocalPref) *api.LocalPrefAttribute { + return &api.LocalPrefAttribute{ LocalPref: a.Value, } } -func (a *LocalPrefAttribute) ToNative() (*bgp.PathAttributeLocalPref, error) { - return bgp.NewPathAttributeLocalPref(a.LocalPref), nil +func NewAtomicAggregateAttributeFromNative(a *bgp.PathAttributeAtomicAggregate) *api.AtomicAggregateAttribute { + return &api.AtomicAggregateAttribute{} } -func NewAtomicAggregateAttributeFromNative(a *bgp.PathAttributeAtomicAggregate) *AtomicAggregateAttribute { - return &AtomicAggregateAttribute{} -} - -func (a *AtomicAggregateAttribute) ToNative() (*bgp.PathAttributeAtomicAggregate, error) { - return bgp.NewPathAttributeAtomicAggregate(), nil -} - -func NewAggregatorAttributeFromNative(a *bgp.PathAttributeAggregator) *AggregatorAttribute { - return &AggregatorAttribute{ +func NewAggregatorAttributeFromNative(a *bgp.PathAttributeAggregator) *api.AggregatorAttribute { + return &api.AggregatorAttribute{ As: a.Value.AS, Address: a.Value.Address.String(), } } -func (a *AggregatorAttribute) ToNative() (*bgp.PathAttributeAggregator, error) { - if net.ParseIP(a.Address).To4() == nil { - return nil, fmt.Errorf("invalid aggregator address: %s", a.Address) - } - return bgp.NewPathAttributeAggregator(a.As, a.Address), nil -} - -func NewCommunitiesAttributeFromNative(a *bgp.PathAttributeCommunities) *CommunitiesAttribute { - return &CommunitiesAttribute{ +func NewCommunitiesAttributeFromNative(a *bgp.PathAttributeCommunities) *api.CommunitiesAttribute { + return &api.CommunitiesAttribute{ Communities: a.Value, } } -func (a *CommunitiesAttribute) ToNative() (*bgp.PathAttributeCommunities, error) { - return bgp.NewPathAttributeCommunities(a.Communities), nil -} - -func NewOriginatorIdAttributeFromNative(a *bgp.PathAttributeOriginatorId) *OriginatorIdAttribute { - return &OriginatorIdAttribute{ +func NewOriginatorIdAttributeFromNative(a *bgp.PathAttributeOriginatorId) *api.OriginatorIdAttribute { + return &api.OriginatorIdAttribute{ Id: a.Value.String(), } } -func (a *OriginatorIdAttribute) ToNative() (*bgp.PathAttributeOriginatorId, error) { - if net.ParseIP(a.Id).To4() == nil { - return nil, fmt.Errorf("invalid originator id: %s", a.Id) - } - return bgp.NewPathAttributeOriginatorId(a.Id), nil -} - -func NewClusterListAttributeFromNative(a *bgp.PathAttributeClusterList) *ClusterListAttribute { +func NewClusterListAttributeFromNative(a *bgp.PathAttributeClusterList) *api.ClusterListAttribute { ids := make([]string, 0, len(a.Value)) for _, id := range a.Value { ids = append(ids, id.String()) } - return &ClusterListAttribute{ + return &api.ClusterListAttribute{ Ids: ids, } } -func (a *ClusterListAttribute) ToNative() (*bgp.PathAttributeClusterList, error) { - for _, id := range a.Ids { - if net.ParseIP(id).To4() == nil { - return nil, fmt.Errorf("invalid cluster list: %s", a.Ids) - } - } - return bgp.NewPathAttributeClusterList(a.Ids), nil -} - func MarshalRD(rd bgp.RouteDistinguisherInterface) *any.Any { var r proto.Message switch v := rd.(type) { case *bgp.RouteDistinguisherTwoOctetAS: - r = &RouteDistinguisherTwoOctetAS{ + r = &api.RouteDistinguisherTwoOctetAS{ Admin: uint32(v.Admin), Assigned: v.Assigned, } case *bgp.RouteDistinguisherIPAddressAS: - r = &RouteDistinguisherIPAddress{ + r = &api.RouteDistinguisherIPAddress{ Admin: v.Admin.String(), Assigned: uint32(v.Assigned), } case *bgp.RouteDistinguisherFourOctetAS: - r = &RouteDistinguisherFourOctetAS{ + r = &api.RouteDistinguisherFourOctetAS{ Admin: v.Admin, Assigned: uint32(v.Assigned), } @@ -190,28 +182,28 @@ func UnmarshalRD(a *any.Any) (bgp.RouteDistinguisherInterface, error) { return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) } switch v := value.Message.(type) { - case *RouteDistinguisherTwoOctetAS: + case *api.RouteDistinguisherTwoOctetAS: return bgp.NewRouteDistinguisherTwoOctetAS(uint16(v.Admin), v.Assigned), nil - case *RouteDistinguisherIPAddress: + case *api.RouteDistinguisherIPAddress: rd := bgp.NewRouteDistinguisherIPAddressAS(v.Admin, uint16(v.Assigned)) if rd == nil { return nil, fmt.Errorf("invalid address for route distinguisher: %s", v.Admin) } return rd, nil - case *RouteDistinguisherFourOctetAS: + case *api.RouteDistinguisherFourOctetAS: return bgp.NewRouteDistinguisherFourOctetAS(v.Admin, uint16(v.Assigned)), nil } return nil, fmt.Errorf("invalid route distinguisher type: %s", a.TypeUrl) } -func NewEthernetSegmentIdentifierFromNative(a *bgp.EthernetSegmentIdentifier) *EthernetSegmentIdentifier { - return &EthernetSegmentIdentifier{ +func NewEthernetSegmentIdentifierFromNative(a *bgp.EthernetSegmentIdentifier) *api.EthernetSegmentIdentifier { + return &api.EthernetSegmentIdentifier{ Type: uint32(a.Type), Value: a.Value, } } -func (a *EthernetSegmentIdentifier) ToNative() (*bgp.EthernetSegmentIdentifier, error) { +func unmarshalESI(a *api.EthernetSegmentIdentifier) (*bgp.EthernetSegmentIdentifier, error) { return &bgp.EthernetSegmentIdentifier{ Type: bgp.ESIType(a.Type), Value: a.Value, @@ -224,50 +216,50 @@ func MarshalFlowSpecRules(values []bgp.FlowSpecComponentInterface) []*any.Any { var rule proto.Message switch v := value.(type) { case *bgp.FlowSpecDestinationPrefix: - rule = &FlowSpecIPPrefix{ + rule = &api.FlowSpecIPPrefix{ Type: uint32(bgp.FLOW_SPEC_TYPE_DST_PREFIX), PrefixLen: uint32(v.Prefix.(*bgp.IPAddrPrefix).Length), Prefix: v.Prefix.(*bgp.IPAddrPrefix).Prefix.String(), } case *bgp.FlowSpecSourcePrefix: - rule = &FlowSpecIPPrefix{ + rule = &api.FlowSpecIPPrefix{ Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_PREFIX), PrefixLen: uint32(v.Prefix.(*bgp.IPAddrPrefix).Length), Prefix: v.Prefix.(*bgp.IPAddrPrefix).Prefix.String(), } case *bgp.FlowSpecDestinationPrefix6: - rule = &FlowSpecIPPrefix{ + rule = &api.FlowSpecIPPrefix{ Type: uint32(bgp.FLOW_SPEC_TYPE_DST_PREFIX), PrefixLen: uint32(v.Prefix.(*bgp.IPv6AddrPrefix).Length), Prefix: v.Prefix.(*bgp.IPv6AddrPrefix).Prefix.String(), Offset: uint32(v.Offset), } case *bgp.FlowSpecSourcePrefix6: - rule = &FlowSpecIPPrefix{ + rule = &api.FlowSpecIPPrefix{ Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_PREFIX), PrefixLen: uint32(v.Prefix.(*bgp.IPv6AddrPrefix).Length), Prefix: v.Prefix.(*bgp.IPv6AddrPrefix).Prefix.String(), Offset: uint32(v.Offset), } case *bgp.FlowSpecSourceMac: - rule = &FlowSpecMAC{ + rule = &api.FlowSpecMAC{ Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_MAC), Address: v.Mac.String(), } case *bgp.FlowSpecDestinationMac: - rule = &FlowSpecMAC{ + rule = &api.FlowSpecMAC{ Type: uint32(bgp.FLOW_SPEC_TYPE_DST_MAC), Address: v.Mac.String(), } case *bgp.FlowSpecComponent: - items := make([]*FlowSpecComponentItem, 0, len(v.Items)) + items := make([]*api.FlowSpecComponentItem, 0, len(v.Items)) for _, i := range v.Items { - items = append(items, &FlowSpecComponentItem{ + items = append(items, &api.FlowSpecComponentItem{ Op: uint32(i.Op), Value: i.Value, }) } - rule = &FlowSpecComponent{ + rule = &api.FlowSpecComponent{ Type: uint32(v.Type()), Items: items, } @@ -287,7 +279,7 @@ func UnmarshalFlowSpecRules(values []*any.Any) ([]bgp.FlowSpecComponentInterface return nil, fmt.Errorf("failed to unmarshal flow spec component: %s", err) } switch v := value.Message.(type) { - case *FlowSpecIPPrefix: + case *api.FlowSpecIPPrefix: typ := bgp.BGPFlowSpecType(v.Type) isIPv4 := net.ParseIP(v.Prefix).To4() != nil switch { @@ -300,7 +292,7 @@ func UnmarshalFlowSpecRules(values []*any.Any) ([]bgp.FlowSpecComponentInterface case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && !isIPv4: rule = bgp.NewFlowSpecSourcePrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) } - case *FlowSpecMAC: + case *api.FlowSpecMAC: typ := bgp.BGPFlowSpecType(v.Type) mac, err := net.ParseMAC(v.Address) if err != nil { @@ -312,7 +304,7 @@ func UnmarshalFlowSpecRules(values []*any.Any) ([]bgp.FlowSpecComponentInterface case bgp.FLOW_SPEC_TYPE_DST_MAC: rule = bgp.NewFlowSpecDestinationMac(mac) } - case *FlowSpecComponent: + case *api.FlowSpecComponent: items := make([]*bgp.FlowSpecComponentItem, 0, len(v.Items)) for _, item := range v.Items { items = append(items, bgp.NewFlowSpecComponentItem(uint8(item.Op), item.Value)) @@ -332,46 +324,46 @@ func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any { switch v := value.(type) { case *bgp.IPAddrPrefix: - nlri = &IPAddressPrefix{ + nlri = &api.IPAddressPrefix{ PrefixLen: uint32(v.Length), Prefix: v.Prefix.String(), } case *bgp.IPv6AddrPrefix: - nlri = &IPAddressPrefix{ + nlri = &api.IPAddressPrefix{ PrefixLen: uint32(v.Length), Prefix: v.Prefix.String(), } case *bgp.LabeledIPAddrPrefix: - nlri = &LabeledIPAddressPrefix{ + nlri = &api.LabeledIPAddressPrefix{ Labels: v.Labels.Labels, PrefixLen: uint32(v.IPPrefixLen()), Prefix: v.Prefix.String(), } case *bgp.LabeledIPv6AddrPrefix: - nlri = &LabeledIPAddressPrefix{ + nlri = &api.LabeledIPAddressPrefix{ Labels: v.Labels.Labels, PrefixLen: uint32(v.IPPrefixLen()), Prefix: v.Prefix.String(), } case *bgp.EncapNLRI: - nlri = &EncapsulationNLRI{ + nlri = &api.EncapsulationNLRI{ Address: v.String(), } case *bgp.Encapv6NLRI: - nlri = &EncapsulationNLRI{ + nlri = &api.EncapsulationNLRI{ Address: v.String(), } case *bgp.EVPNNLRI: switch r := v.RouteTypeData.(type) { case *bgp.EVPNEthernetAutoDiscoveryRoute: - nlri = &EVPNEthernetAutoDiscoveryRoute{ + nlri = &api.EVPNEthernetAutoDiscoveryRoute{ Rd: MarshalRD(r.RD), Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), EthernetTag: r.ETag, Label: r.Label, } case *bgp.EVPNMacIPAdvertisementRoute: - nlri = &EVPNMACIPAdvertisementRoute{ + nlri = &api.EVPNMACIPAdvertisementRoute{ Rd: MarshalRD(r.RD), Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), EthernetTag: r.ETag, @@ -380,19 +372,19 @@ func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any { Labels: r.Labels, } case *bgp.EVPNMulticastEthernetTagRoute: - nlri = &EVPNInclusiveMulticastEthernetTagRoute{ + nlri = &api.EVPNInclusiveMulticastEthernetTagRoute{ Rd: MarshalRD(r.RD), EthernetTag: r.ETag, IpAddress: r.IPAddress.String(), } case *bgp.EVPNEthernetSegmentRoute: - nlri = &EVPNEthernetSegmentRoute{ + nlri = &api.EVPNEthernetSegmentRoute{ Rd: MarshalRD(r.RD), Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), IpAddress: r.IPAddress.String(), } case *bgp.EVPNIPPrefixRoute: - nlri = &EVPNIPPrefixRoute{ + nlri = &api.EVPNIPPrefixRoute{ Rd: MarshalRD(r.RD), Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), EthernetTag: r.ETag, @@ -402,44 +394,44 @@ func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any { } } case *bgp.LabeledVPNIPAddrPrefix: - nlri = &LabeledVPNIPAddressPrefix{ + nlri = &api.LabeledVPNIPAddressPrefix{ Labels: v.Labels.Labels, Rd: MarshalRD(v.RD), PrefixLen: uint32(v.IPPrefixLen()), Prefix: v.Prefix.String(), } case *bgp.LabeledVPNIPv6AddrPrefix: - nlri = &LabeledVPNIPAddressPrefix{ + nlri = &api.LabeledVPNIPAddressPrefix{ Labels: v.Labels.Labels, Rd: MarshalRD(v.RD), PrefixLen: uint32(v.IPPrefixLen()), Prefix: v.Prefix.String(), } case *bgp.RouteTargetMembershipNLRI: - nlri = &RouteTargetMembershipNLRI{ + nlri = &api.RouteTargetMembershipNLRI{ As: v.AS, Rt: MarshalRT(v.RouteTarget), } case *bgp.FlowSpecIPv4Unicast: - nlri = &FlowSpecNLRI{ + nlri = &api.FlowSpecNLRI{ Rules: MarshalFlowSpecRules(v.Value), } case *bgp.FlowSpecIPv6Unicast: - nlri = &FlowSpecNLRI{ + nlri = &api.FlowSpecNLRI{ Rules: MarshalFlowSpecRules(v.Value), } case *bgp.FlowSpecIPv4VPN: - nlri = &VPNFlowSpecNLRI{ + nlri = &api.VPNFlowSpecNLRI{ Rd: MarshalRD(v.RD()), Rules: MarshalFlowSpecRules(v.Value), } case *bgp.FlowSpecIPv6VPN: - nlri = &VPNFlowSpecNLRI{ + nlri = &api.VPNFlowSpecNLRI{ Rd: MarshalRD(v.RD()), Rules: MarshalFlowSpecRules(v.Value), } case *bgp.FlowSpecL2VPN: - nlri = &VPNFlowSpecNLRI{ + nlri = &api.VPNFlowSpecNLRI{ Rd: MarshalRD(v.RD()), Rules: MarshalFlowSpecRules(v.Value), } @@ -466,52 +458,52 @@ func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, er } switch v := value.Message.(type) { - case *IPAddressPrefix: + case *api.IPAddressPrefix: switch rf { case bgp.RF_IPv4_UC: nlri = bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix) case bgp.RF_IPv6_UC: nlri = bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix) } - case *LabeledIPAddressPrefix: + case *api.LabeledIPAddressPrefix: switch rf { case bgp.RF_IPv4_MPLS: nlri = bgp.NewLabeledIPAddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...)) case bgp.RF_IPv6_MPLS: nlri = bgp.NewLabeledIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...)) } - case *EncapsulationNLRI: + case *api.EncapsulationNLRI: switch rf { case bgp.RF_IPv4_ENCAP: nlri = bgp.NewEncapNLRI(v.Address) case bgp.RF_IPv6_ENCAP: nlri = bgp.NewEncapv6NLRI(v.Address) } - case *EVPNEthernetAutoDiscoveryRoute: + case *api.EVPNEthernetAutoDiscoveryRoute: if rf == bgp.RF_EVPN { rd, err := UnmarshalRD(v.Rd) if err != nil { return nil, err } - esi, err := v.Esi.ToNative() + esi, err := unmarshalESI(v.Esi) if err != nil { return nil, err } nlri = bgp.NewEVPNEthernetAutoDiscoveryRoute(rd, *esi, v.EthernetTag, v.Label) } - case *EVPNMACIPAdvertisementRoute: + case *api.EVPNMACIPAdvertisementRoute: if rf == bgp.RF_EVPN { rd, err := UnmarshalRD(v.Rd) if err != nil { return nil, err } - esi, err := v.Esi.ToNative() + esi, err := unmarshalESI(v.Esi) if err != nil { return nil, err } nlri = bgp.NewEVPNMacIPAdvertisementRoute(rd, *esi, v.EthernetTag, v.MacAddress, v.IpAddress, v.Labels) } - case *EVPNInclusiveMulticastEthernetTagRoute: + case *api.EVPNInclusiveMulticastEthernetTagRoute: if rf == bgp.RF_EVPN { rd, err := UnmarshalRD(v.Rd) if err != nil { @@ -519,31 +511,31 @@ func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, er } nlri = bgp.NewEVPNMulticastEthernetTagRoute(rd, v.EthernetTag, v.IpAddress) } - case *EVPNEthernetSegmentRoute: + case *api.EVPNEthernetSegmentRoute: if rf == bgp.RF_EVPN { rd, err := UnmarshalRD(v.Rd) if err != nil { return nil, err } - esi, err := v.Esi.ToNative() + esi, err := unmarshalESI(v.Esi) if err != nil { return nil, err } nlri = bgp.NewEVPNEthernetSegmentRoute(rd, *esi, v.IpAddress) } - case *EVPNIPPrefixRoute: + case *api.EVPNIPPrefixRoute: if rf == bgp.RF_EVPN { rd, err := UnmarshalRD(v.Rd) if err != nil { return nil, err } - esi, err := v.Esi.ToNative() + esi, err := unmarshalESI(v.Esi) if err != nil { return nil, err } nlri = bgp.NewEVPNIPPrefixRoute(rd, *esi, v.EthernetTag, uint8(v.IpPrefixLen), v.IpPrefix, v.GwAddress, v.Label) } - case *LabeledVPNIPAddressPrefix: + case *api.LabeledVPNIPAddressPrefix: rd, err := UnmarshalRD(v.Rd) if err != nil { return nil, err @@ -554,13 +546,13 @@ func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, er case bgp.RF_IPv6_VPN: nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) } - case *RouteTargetMembershipNLRI: + case *api.RouteTargetMembershipNLRI: rt, err := UnmarshalRT(v.Rt) if err != nil { return nil, err } nlri = bgp.NewRouteTargetMembershipNLRI(v.As, rt) - case *FlowSpecNLRI: + case *api.FlowSpecNLRI: rules, err := UnmarshalFlowSpecRules(v.Rules) if err != nil { return nil, err @@ -571,7 +563,7 @@ func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, er case bgp.RF_FS_IPv6_UC: nlri = bgp.NewFlowSpecIPv6Unicast(rules) } - case *VPNFlowSpecNLRI: + case *api.VPNFlowSpecNLRI: rd, err := UnmarshalRD(v.Rd) if err != nil { return nil, err @@ -609,7 +601,7 @@ func UnmarshalNLRIs(rf bgp.RouteFamily, values []*any.Any) ([]bgp.AddrPrefixInte return nlris, nil } -func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *MpReachNLRIAttribute { +func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *api.MpReachNLRIAttribute { var nexthops []string if a.SAFI == bgp.SAFI_FLOW_SPEC_UNICAST || a.SAFI == bgp.SAFI_FLOW_SPEC_VPN { nexthops = nil @@ -619,79 +611,39 @@ func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *MpReach nexthops = append(nexthops, a.LinkLocalNexthop.String()) } } - return &MpReachNLRIAttribute{ + return &api.MpReachNLRIAttribute{ Family: uint32(bgp.AfiSafiToRouteFamily(a.AFI, a.SAFI)), NextHops: nexthops, Nlris: MarshalNLRIs(a.Value), } } -func (a *MpReachNLRIAttribute) ToNative() (*bgp.PathAttributeMpReachNLRI, error) { - rf := bgp.RouteFamily(a.Family) - nlris, err := UnmarshalNLRIs(rf, a.Nlris) - if err != nil { - return nil, err - } - afi, safi := bgp.RouteFamilyToAfiSafi(rf) - nexthop := "0.0.0.0" - var linkLocalNexthop net.IP - if afi == bgp.AFI_IP6 { - nexthop = "::" - if len(a.NextHops) > 1 { - linkLocalNexthop = net.ParseIP(a.NextHops[1]).To16() - if linkLocalNexthop == nil { - return nil, fmt.Errorf("invalid nexthop: %s", a.NextHops[1]) - } - } - } - if safi == bgp.SAFI_FLOW_SPEC_UNICAST || safi == bgp.SAFI_FLOW_SPEC_VPN { - nexthop = "" - } else if len(a.NextHops) > 0 { - nexthop = a.NextHops[0] - if net.ParseIP(nexthop) == nil { - return nil, fmt.Errorf("invalid nexthop: %s", nexthop) - } - } - attr := bgp.NewPathAttributeMpReachNLRI(nexthop, nlris) - attr.LinkLocalNexthop = linkLocalNexthop - return attr, nil -} - -func NewMpUnreachNLRIAttributeFromNative(a *bgp.PathAttributeMpUnreachNLRI) *MpUnreachNLRIAttribute { - return &MpUnreachNLRIAttribute{ +func NewMpUnreachNLRIAttributeFromNative(a *bgp.PathAttributeMpUnreachNLRI) *api.MpUnreachNLRIAttribute { + return &api.MpUnreachNLRIAttribute{ Family: uint32(bgp.AfiSafiToRouteFamily(a.AFI, a.SAFI)), Nlris: MarshalNLRIs(a.Value), } } -func (a *MpUnreachNLRIAttribute) ToNative() (*bgp.PathAttributeMpUnreachNLRI, error) { - rf := bgp.RouteFamily(a.Family) - nlris, err := UnmarshalNLRIs(rf, a.Nlris) - if err != nil { - return nil, err - } - return bgp.NewPathAttributeMpUnreachNLRI(nlris), nil -} - func MarshalRT(rt bgp.ExtendedCommunityInterface) *any.Any { var r proto.Message switch v := rt.(type) { case *bgp.TwoOctetAsSpecificExtended: - r = &TwoOctetAsSpecificExtended{ + r = &api.TwoOctetAsSpecificExtended{ IsTransitive: true, SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), As: uint32(v.AS), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.IPv4AddressSpecificExtended: - r = &IPv4AddressSpecificExtended{ + r = &api.IPv4AddressSpecificExtended{ IsTransitive: true, SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), Address: v.IPv4.String(), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.FourOctetAsSpecificExtended: - r = &FourOctetAsSpecificExtended{ + r = &api.FourOctetAsSpecificExtended{ IsTransitive: true, SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), As: uint32(v.AS), @@ -722,15 +674,15 @@ func UnmarshalRT(a *any.Any) (bgp.ExtendedCommunityInterface, error) { return nil, fmt.Errorf("failed to unmarshal route target: %s", err) } switch v := value.Message.(type) { - case *TwoOctetAsSpecificExtended: + case *api.TwoOctetAsSpecificExtended: return bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.As), v.LocalAdmin, v.IsTransitive), nil - case *IPv4AddressSpecificExtended: + case *api.IPv4AddressSpecificExtended: rt := bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) if rt == nil { return nil, fmt.Errorf("invalid address for ipv4 address specific route target: %s", v.Address) } return rt, nil - case *FourOctetAsSpecificExtended: + case *api.FourOctetAsSpecificExtended: return bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive), nil } return nil, fmt.Errorf("invalid route target type: %s", a.TypeUrl) @@ -748,100 +700,100 @@ func UnmarshalRTs(values []*any.Any) ([]bgp.ExtendedCommunityInterface, error) { return rts, nil } -func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommunities) *ExtendedCommunitiesAttribute { +func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommunities) *api.ExtendedCommunitiesAttribute { communities := make([]*any.Any, 0, len(a.Value)) for _, value := range a.Value { var community proto.Message switch v := value.(type) { case *bgp.TwoOctetAsSpecificExtended: - community = &TwoOctetAsSpecificExtended{ + community = &api.TwoOctetAsSpecificExtended{ IsTransitive: v.IsTransitive, SubType: uint32(v.SubType), As: uint32(v.AS), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.IPv4AddressSpecificExtended: - community = &IPv4AddressSpecificExtended{ + community = &api.IPv4AddressSpecificExtended{ IsTransitive: v.IsTransitive, SubType: uint32(v.SubType), Address: v.IPv4.String(), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.FourOctetAsSpecificExtended: - community = &FourOctetAsSpecificExtended{ + community = &api.FourOctetAsSpecificExtended{ IsTransitive: v.IsTransitive, SubType: uint32(v.SubType), As: uint32(v.AS), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.ValidationExtended: - community = &ValidationExtended{ + community = &api.ValidationExtended{ State: uint32(v.State), } case *bgp.ColorExtended: - community = &ColorExtended{ + community = &api.ColorExtended{ Color: v.Color, } case *bgp.EncapExtended: - community = &EncapExtended{ + community = &api.EncapExtended{ TunnelType: uint32(v.TunnelType), } case *bgp.DefaultGatewayExtended: - community = &DefaultGatewayExtended{} + community = &api.DefaultGatewayExtended{} case *bgp.OpaqueExtended: - community = &OpaqueExtended{ + community = &api.OpaqueExtended{ IsTransitive: v.IsTransitive, Value: v.Value, } case *bgp.ESILabelExtended: - community = &ESILabelExtended{ + community = &api.ESILabelExtended{ IsSingleActive: v.IsSingleActive, Label: v.Label, } case *bgp.ESImportRouteTarget: - community = &ESImportRouteTarget{ + community = &api.ESImportRouteTarget{ EsImport: v.ESImport.String(), } case *bgp.MacMobilityExtended: - community = &MacMobilityExtended{ + community = &api.MacMobilityExtended{ IsSticky: v.IsSticky, SequenceNum: v.Sequence, } case *bgp.RouterMacExtended: - community = &RouterMacExtended{ + community = &api.RouterMacExtended{ Mac: v.Mac.String(), } case *bgp.TrafficRateExtended: - community = &TrafficRateExtended{ + community = &api.TrafficRateExtended{ As: uint32(v.AS), Rate: v.Rate, } case *bgp.TrafficActionExtended: - community = &TrafficActionExtended{ + community = &api.TrafficActionExtended{ Terminal: v.Terminal, Sample: v.Sample, } case *bgp.RedirectTwoOctetAsSpecificExtended: - community = &RedirectTwoOctetAsSpecificExtended{ + community = &api.RedirectTwoOctetAsSpecificExtended{ As: uint32(v.AS), LocalAdmin: v.LocalAdmin, } case *bgp.RedirectIPv4AddressSpecificExtended: - community = &RedirectIPv4AddressSpecificExtended{ + community = &api.RedirectIPv4AddressSpecificExtended{ Address: v.IPv4.String(), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.RedirectFourOctetAsSpecificExtended: - community = &RedirectFourOctetAsSpecificExtended{ + community = &api.RedirectFourOctetAsSpecificExtended{ As: v.AS, LocalAdmin: uint32(v.LocalAdmin), } case *bgp.TrafficRemarkExtended: - community = &TrafficRemarkExtended{ + community = &api.TrafficRemarkExtended{ Dscp: uint32(v.DSCP), } case *bgp.UnknownExtended: - community = &UnknownExtended{ + community = &api.UnknownExtended{ Type: uint32(v.Type), Value: v.Value, } @@ -855,12 +807,12 @@ func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommu an, _ := ptypes.MarshalAny(community) communities = append(communities, an) } - return &ExtendedCommunitiesAttribute{ + return &api.ExtendedCommunitiesAttribute{ Communities: communities, } } -func (a *ExtendedCommunitiesAttribute) ToNative() (*bgp.PathAttributeExtendedCommunities, error) { +func unmarshalExComm(a *api.ExtendedCommunitiesAttribute) (*bgp.PathAttributeExtendedCommunities, error) { communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) for _, an := range a.Communities { var community bgp.ExtendedCommunityInterface @@ -869,43 +821,43 @@ func (a *ExtendedCommunitiesAttribute) ToNative() (*bgp.PathAttributeExtendedCom return nil, fmt.Errorf("failed to unmarshal extended community: %s", err) } switch v := value.Message.(type) { - case *TwoOctetAsSpecificExtended: + case *api.TwoOctetAsSpecificExtended: community = bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.As), v.LocalAdmin, v.IsTransitive) - case *IPv4AddressSpecificExtended: + case *api.IPv4AddressSpecificExtended: community = bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) - case *FourOctetAsSpecificExtended: + case *api.FourOctetAsSpecificExtended: community = bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive) - case *ValidationExtended: + case *api.ValidationExtended: community = bgp.NewValidationExtended(bgp.ValidationState(v.State)) - case *ColorExtended: + case *api.ColorExtended: community = bgp.NewColorExtended(v.Color) - case *EncapExtended: + case *api.EncapExtended: community = bgp.NewEncapExtended(bgp.TunnelType(v.TunnelType)) - case *DefaultGatewayExtended: + case *api.DefaultGatewayExtended: community = bgp.NewDefaultGatewayExtended() - case *OpaqueExtended: + case *api.OpaqueExtended: community = bgp.NewOpaqueExtended(v.IsTransitive, v.Value) - case *ESILabelExtended: + case *api.ESILabelExtended: community = bgp.NewESILabelExtended(v.Label, v.IsSingleActive) - case *ESImportRouteTarget: + case *api.ESImportRouteTarget: community = bgp.NewESImportRouteTarget(v.EsImport) - case *MacMobilityExtended: + case *api.MacMobilityExtended: community = bgp.NewMacMobilityExtended(v.SequenceNum, v.IsSticky) - case *RouterMacExtended: + case *api.RouterMacExtended: community = bgp.NewRoutersMacExtended(v.Mac) - case *TrafficRateExtended: + case *api.TrafficRateExtended: community = bgp.NewTrafficRateExtended(uint16(v.As), v.Rate) - case *TrafficActionExtended: + case *api.TrafficActionExtended: community = bgp.NewTrafficActionExtended(v.Terminal, v.Sample) - case *RedirectTwoOctetAsSpecificExtended: + case *api.RedirectTwoOctetAsSpecificExtended: community = bgp.NewRedirectTwoOctetAsSpecificExtended(uint16(v.As), v.LocalAdmin) - case *RedirectIPv4AddressSpecificExtended: + case *api.RedirectIPv4AddressSpecificExtended: community = bgp.NewRedirectIPv4AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) - case *RedirectFourOctetAsSpecificExtended: + case *api.RedirectFourOctetAsSpecificExtended: community = bgp.NewRedirectFourOctetAsSpecificExtended(v.As, uint16(v.LocalAdmin)) - case *TrafficRemarkExtended: + case *api.TrafficRemarkExtended: community = bgp.NewTrafficRemarkExtended(uint8(v.Dscp)) - case *UnknownExtended: + case *api.UnknownExtended: community = bgp.NewUnknownExtended(bgp.ExtendedCommunityAttrType(v.Type), v.Value) } if community == nil { @@ -916,48 +868,33 @@ func (a *ExtendedCommunitiesAttribute) ToNative() (*bgp.PathAttributeExtendedCom return bgp.NewPathAttributeExtendedCommunities(communities), nil } -func NewAs4PathAttributeFromNative(a *bgp.PathAttributeAs4Path) *As4PathAttribute { - segments := make([]*AsSegment, 0, len(a.Value)) +func NewAs4PathAttributeFromNative(a *bgp.PathAttributeAs4Path) *api.As4PathAttribute { + segments := make([]*api.AsSegment, 0, len(a.Value)) for _, param := range a.Value { - segments = append(segments, &AsSegment{ + segments = append(segments, &api.AsSegment{ Type: uint32(param.Type), Numbers: param.AS, }) } - return &As4PathAttribute{ + return &api.As4PathAttribute{ Segments: segments, } } -func (a *As4PathAttribute) ToNative() (*bgp.PathAttributeAs4Path, error) { - params := make([]*bgp.As4PathParam, 0, len(a.Segments)) - for _, segment := range a.Segments { - params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) - } - return bgp.NewPathAttributeAs4Path(params), nil -} - -func NewAs4AggregatorAttributeFromNative(a *bgp.PathAttributeAs4Aggregator) *As4AggregatorAttribute { - return &As4AggregatorAttribute{ +func NewAs4AggregatorAttributeFromNative(a *bgp.PathAttributeAs4Aggregator) *api.As4AggregatorAttribute { + return &api.As4AggregatorAttribute{ As: a.Value.AS, Address: a.Value.Address.String(), } } -func (a *As4AggregatorAttribute) ToNative() (*bgp.PathAttributeAs4Aggregator, error) { - if net.ParseIP(a.Address).To4() == nil { - return nil, fmt.Errorf("invalid as4 aggregator address: %s", a.Address) - } - return bgp.NewPathAttributeAs4Aggregator(a.As, a.Address), nil -} - -func NewPmsiTunnelAttributeFromNative(a *bgp.PathAttributePmsiTunnel) *PmsiTunnelAttribute { +func NewPmsiTunnelAttributeFromNative(a *bgp.PathAttributePmsiTunnel) *api.PmsiTunnelAttribute { var flags uint32 if a.IsLeafInfoRequired { flags |= 0x01 } id, _ := a.TunnelID.Serialize() - return &PmsiTunnelAttribute{ + return &api.PmsiTunnelAttribute{ Flags: flags, Type: uint32(a.TunnelType), Label: a.Label, @@ -965,48 +902,28 @@ func NewPmsiTunnelAttributeFromNative(a *bgp.PathAttributePmsiTunnel) *PmsiTunne } } -func (a *PmsiTunnelAttribute) ToNative() (*bgp.PathAttributePmsiTunnel, error) { - typ := bgp.PmsiTunnelType(a.Type) - var isLeafInfoRequired bool - if a.Flags&0x01 > 0 { - isLeafInfoRequired = true - } - var id bgp.PmsiTunnelIDInterface - switch typ { - case bgp.PMSI_TUNNEL_TYPE_INGRESS_REPL: - ip := net.IP(a.Id) - if ip.To4() == nil && ip.To16() == nil { - return nil, fmt.Errorf("invalid pmsi tunnel identifier: %s", a.Id) - } - id = bgp.NewIngressReplTunnelID(ip.String()) - default: - id = bgp.NewDefaultPmsiTunnelID(a.Id) - } - return bgp.NewPathAttributePmsiTunnel(typ, isLeafInfoRequired, a.Label, id), nil -} - -func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *TunnelEncapAttribute { - tlvs := make([]*TunnelEncapTLV, 0, len(a.Value)) +func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *api.TunnelEncapAttribute { + tlvs := make([]*api.TunnelEncapTLV, 0, len(a.Value)) for _, v := range a.Value { subTlvs := make([]*any.Any, 0, len(v.Value)) for _, s := range v.Value { var subTlv proto.Message switch sv := s.(type) { case *bgp.TunnelEncapSubTLVEncapsulation: - subTlv = &TunnelEncapSubTLVEncapsulation{ + subTlv = &api.TunnelEncapSubTLVEncapsulation{ Key: sv.Key, Cookie: sv.Cookie, } case *bgp.TunnelEncapSubTLVProtocol: - subTlv = &TunnelEncapSubTLVProtocol{ + subTlv = &api.TunnelEncapSubTLVProtocol{ Protocol: uint32(sv.Protocol), } case *bgp.TunnelEncapSubTLVColor: - subTlv = &TunnelEncapSubTLVColor{ + subTlv = &api.TunnelEncapSubTLVColor{ Color: sv.Color, } case *bgp.TunnelEncapSubTLVUnknown: - subTlv = &TunnelEncapSubTLVUnknown{ + subTlv = &api.TunnelEncapSubTLVUnknown{ Type: uint32(sv.Type), Value: sv.Value, } @@ -1014,59 +931,30 @@ func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *TunnelE an, _ := ptypes.MarshalAny(subTlv) subTlvs = append(subTlvs, an) } - tlvs = append(tlvs, &TunnelEncapTLV{ + tlvs = append(tlvs, &api.TunnelEncapTLV{ Type: uint32(v.Type), Tlvs: subTlvs, }) } - return &TunnelEncapAttribute{ + return &api.TunnelEncapAttribute{ Tlvs: tlvs, } } -func (a *TunnelEncapAttribute) ToNative() (*bgp.PathAttributeTunnelEncap, error) { - tlvs := make([]*bgp.TunnelEncapTLV, 0, len(a.Tlvs)) - for _, tlv := range a.Tlvs { - subTlvs := make([]bgp.TunnelEncapSubTLVInterface, 0, len(tlv.Tlvs)) - for _, an := range tlv.Tlvs { - var subTlv bgp.TunnelEncapSubTLVInterface - var subValue ptypes.DynamicAny - if err := ptypes.UnmarshalAny(an, &subValue); err != nil { - return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err) - } - switch sv := subValue.Message.(type) { - case *TunnelEncapSubTLVEncapsulation: - subTlv = bgp.NewTunnelEncapSubTLVEncapsulation(sv.Key, sv.Cookie) - case *TunnelEncapSubTLVProtocol: - subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol)) - case *TunnelEncapSubTLVColor: - subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color) - case *TunnelEncapSubTLVUnknown: - subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value) - default: - return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v", subValue.Message) - } - subTlvs = append(subTlvs, subTlv) - } - tlvs = append(tlvs, bgp.NewTunnelEncapTLV(bgp.TunnelType(tlv.Type), subTlvs)) - } - return bgp.NewPathAttributeTunnelEncap(tlvs), nil -} - -func NewIP6ExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeIP6ExtendedCommunities) *IP6ExtendedCommunitiesAttribute { +func NewIP6ExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeIP6ExtendedCommunities) *api.IP6ExtendedCommunitiesAttribute { communities := make([]*any.Any, 0, len(a.Value)) for _, value := range a.Value { var community proto.Message switch v := value.(type) { case *bgp.IPv6AddressSpecificExtended: - community = &IPv6AddressSpecificExtended{ + community = &api.IPv6AddressSpecificExtended{ IsTransitive: v.IsTransitive, SubType: uint32(v.SubType), Address: v.IPv6.String(), LocalAdmin: uint32(v.LocalAdmin), } case *bgp.RedirectIPv6AddressSpecificExtended: - community = &RedirectIPv6AddressSpecificExtended{ + community = &api.RedirectIPv6AddressSpecificExtended{ Address: v.IPv6.String(), LocalAdmin: uint32(v.LocalAdmin), } @@ -1080,44 +968,22 @@ func NewIP6ExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeIP6Extende an, _ := ptypes.MarshalAny(community) communities = append(communities, an) } - return &IP6ExtendedCommunitiesAttribute{ + return &api.IP6ExtendedCommunitiesAttribute{ Communities: communities, } } -func (a *IP6ExtendedCommunitiesAttribute) ToNative() (*bgp.PathAttributeIP6ExtendedCommunities, error) { - communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) - for _, an := range a.Communities { - var community bgp.ExtendedCommunityInterface - var value ptypes.DynamicAny - if err := ptypes.UnmarshalAny(an, &value); err != nil { - return nil, fmt.Errorf("failed to unmarshal ipv6 extended community: %s", err) - } - switch v := value.Message.(type) { - case *IPv6AddressSpecificExtended: - community = bgp.NewIPv6AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) - case *RedirectIPv6AddressSpecificExtended: - community = bgp.NewRedirectIPv6AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) - } - if community == nil { - return nil, fmt.Errorf("invalid ipv6 extended community: %v", value.Message) - } - communities = append(communities, community) - } - return bgp.NewPathAttributeIP6ExtendedCommunities(communities), nil -} - -func NewAigpAttributeFromNative(a *bgp.PathAttributeAigp) *AigpAttribute { +func NewAigpAttributeFromNative(a *bgp.PathAttributeAigp) *api.AigpAttribute { tlvs := make([]*any.Any, 0, len(a.Values)) for _, value := range a.Values { var tlv proto.Message switch v := value.(type) { case *bgp.AigpTLVIgpMetric: - tlv = &AigpTLVIGPMetric{ + tlv = &api.AigpTLVIGPMetric{ Metric: v.Metric, } case *bgp.AigpTLVDefault: - tlv = &AigpTLVUnknown{ + tlv = &api.AigpTLVUnknown{ Type: uint32(v.Type()), Value: v.Value, } @@ -1125,67 +991,33 @@ func NewAigpAttributeFromNative(a *bgp.PathAttributeAigp) *AigpAttribute { an, _ := ptypes.MarshalAny(tlv) tlvs = append(tlvs, an) } - return &AigpAttribute{ + return &api.AigpAttribute{ Tlvs: tlvs, } } -func (a *AigpAttribute) ToNative() (*bgp.PathAttributeAigp, error) { - tlvs := make([]bgp.AigpTLVInterface, 0, len(a.Tlvs)) - for _, an := range a.Tlvs { - var tlv bgp.AigpTLVInterface - var value ptypes.DynamicAny - if err := ptypes.UnmarshalAny(an, &value); err != nil { - return nil, fmt.Errorf("failed to unmarshal aigp attribute tlv: %s", err) - } - switch v := value.Message.(type) { - case *AigpTLVIGPMetric: - tlv = bgp.NewAigpTLVIgpMetric(v.Metric) - case *AigpTLVUnknown: - tlv = bgp.NewAigpTLVDefault(bgp.AigpTLVType(v.Type), v.Value) - } - if tlv == nil { - return nil, fmt.Errorf("invalid aigp attribute tlv: %v", value.Message) - } - tlvs = append(tlvs, tlv) - } - return bgp.NewPathAttributeAigp(tlvs), nil -} - -func NewLargeCommunitiesAttributeFromNative(a *bgp.PathAttributeLargeCommunities) *LargeCommunitiesAttribute { - communities := make([]*LargeCommunity, 0, len(a.Values)) +func NewLargeCommunitiesAttributeFromNative(a *bgp.PathAttributeLargeCommunities) *api.LargeCommunitiesAttribute { + communities := make([]*api.LargeCommunity, 0, len(a.Values)) for _, v := range a.Values { - communities = append(communities, &LargeCommunity{ + communities = append(communities, &api.LargeCommunity{ GlobalAdmin: v.ASN, LocalData1: v.LocalData1, LocalData2: v.LocalData2, }) } - return &LargeCommunitiesAttribute{ + return &api.LargeCommunitiesAttribute{ Communities: communities, } } -func (a *LargeCommunitiesAttribute) ToNative() (*bgp.PathAttributeLargeCommunities, error) { - communities := make([]*bgp.LargeCommunity, 0, len(a.Communities)) - for _, c := range a.Communities { - communities = append(communities, bgp.NewLargeCommunity(c.GlobalAdmin, c.LocalData1, c.LocalData2)) - } - return bgp.NewPathAttributeLargeCommunities(communities), nil -} - -func NewUnknownAttributeFromNative(a *bgp.PathAttributeUnknown) *UnknownAttribute { - return &UnknownAttribute{ +func NewUnknownAttributeFromNative(a *bgp.PathAttributeUnknown) *api.UnknownAttribute { + return &api.UnknownAttribute{ Flags: uint32(a.Flags), Type: uint32(a.Type), Value: a.Value, } } -func (a *UnknownAttribute) ToNative() (*bgp.PathAttributeUnknown, error) { - return bgp.NewPathAttributeUnknown(bgp.BGPAttrFlag(a.Flags), bgp.BGPAttrType(a.Type), a.Value), nil -} - func MarshalPathAttributes(attrList []bgp.PathAttributeInterface) []*any.Any { anyList := make([]*any.Any, 0, len(attrList)) for _, attr := range attrList { @@ -1262,67 +1094,10 @@ func UnmarshalPathAttributes(values []*any.Any) ([]bgp.PathAttributeInterface, e attrList := make([]bgp.PathAttributeInterface, 0, len(values)) typeMap := make(map[bgp.BGPAttrType]struct{}) for _, an := range values { - var attr bgp.PathAttributeInterface - var value ptypes.DynamicAny - err := ptypes.UnmarshalAny(an, &value) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal path attribute: %s", err) - } - switch v := value.Message.(type) { - case *OriginAttribute: - attr, err = v.ToNative() - case *AsPathAttribute: - attr, err = v.ToNative() - case *NextHopAttribute: - attr, err = v.ToNative() - case *MultiExitDiscAttribute: - attr, err = v.ToNative() - case *LocalPrefAttribute: - attr, err = v.ToNative() - case *AtomicAggregateAttribute: - attr, err = v.ToNative() - case *AggregatorAttribute: - attr, err = v.ToNative() - case *CommunitiesAttribute: - attr, err = v.ToNative() - case *OriginatorIdAttribute: - attr, err = v.ToNative() - case *ClusterListAttribute: - attr, err = v.ToNative() - case *MpReachNLRIAttribute: - var nlri *bgp.PathAttributeMpReachNLRI - nlri, err = v.ToNative() - if len(nlri.Value) > 1 { - return nil, fmt.Errorf("multiple nlri in a single mp_reach_nlri are not supported") - } - attr = nlri - case *MpUnreachNLRIAttribute: - attr, err = v.ToNative() - case *ExtendedCommunitiesAttribute: - attr, err = v.ToNative() - case *As4PathAttribute: - attr, err = v.ToNative() - case *As4AggregatorAttribute: - attr, err = v.ToNative() - case *PmsiTunnelAttribute: - attr, err = v.ToNative() - case *TunnelEncapAttribute: - attr, err = v.ToNative() - case *IP6ExtendedCommunitiesAttribute: - attr, err = v.ToNative() - case *AigpAttribute: - attr, err = v.ToNative() - case *LargeCommunitiesAttribute: - attr, err = v.ToNative() - case *UnknownAttribute: - attr, err = v.ToNative() - } + attr, err := unmarshalAttribute(an) if err != nil { return nil, err } - if attr == nil { - return nil, fmt.Errorf("invalid value type for path attribute: %s", value.Message) - } if _, ok := typeMap[attr.GetType()]; ok { return nil, fmt.Errorf("duplicated path attribute type: %d", attr.GetType()) } @@ -1331,3 +1106,197 @@ func UnmarshalPathAttributes(values []*any.Any) ([]bgp.PathAttributeInterface, e } return attrList, nil } + +func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) + } + switch a := value.Message.(type) { + case *api.OriginAttribute: + return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil + case *api.AsPathAttribute: + params := make([]bgp.AsPathParamInterface, 0, len(a.Segments)) + for _, segment := range a.Segments { + params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) + } + return bgp.NewPathAttributeAsPath(params), nil + case *api.NextHopAttribute: + nexthop := net.ParseIP(a.NextHop).To4() + if nexthop == nil { + return nil, fmt.Errorf("invalid nexthop address: %s", a.NextHop) + } + return bgp.NewPathAttributeNextHop(a.NextHop), nil + case *api.MultiExitDiscAttribute: + return bgp.NewPathAttributeMultiExitDisc(a.Med), nil + case *api.LocalPrefAttribute: + return bgp.NewPathAttributeLocalPref(a.LocalPref), nil + case *api.AtomicAggregateAttribute: + return bgp.NewPathAttributeAtomicAggregate(), nil + case *api.AggregatorAttribute: + if net.ParseIP(a.Address).To4() == nil { + return nil, fmt.Errorf("invalid aggregator address: %s", a.Address) + } + return bgp.NewPathAttributeAggregator(a.As, a.Address), nil + case *api.CommunitiesAttribute: + return bgp.NewPathAttributeCommunities(a.Communities), nil + case *api.OriginatorIdAttribute: + if net.ParseIP(a.Id).To4() == nil { + return nil, fmt.Errorf("invalid originator id: %s", a.Id) + } + return bgp.NewPathAttributeOriginatorId(a.Id), nil + case *api.ClusterListAttribute: + for _, id := range a.Ids { + if net.ParseIP(id).To4() == nil { + return nil, fmt.Errorf("invalid cluster list: %s", a.Ids) + } + } + return bgp.NewPathAttributeClusterList(a.Ids), nil + case *api.MpReachNLRIAttribute: + rf := bgp.RouteFamily(a.Family) + nlris, err := UnmarshalNLRIs(rf, a.Nlris) + if err != nil { + return nil, err + } + afi, safi := bgp.RouteFamilyToAfiSafi(rf) + nexthop := "0.0.0.0" + var linkLocalNexthop net.IP + if afi == bgp.AFI_IP6 { + nexthop = "::" + if len(a.NextHops) > 1 { + linkLocalNexthop = net.ParseIP(a.NextHops[1]).To16() + if linkLocalNexthop == nil { + return nil, fmt.Errorf("invalid nexthop: %s", a.NextHops[1]) + } + } + } + if safi == bgp.SAFI_FLOW_SPEC_UNICAST || safi == bgp.SAFI_FLOW_SPEC_VPN { + nexthop = "" + } else if len(a.NextHops) > 0 { + nexthop = a.NextHops[0] + if net.ParseIP(nexthop) == nil { + return nil, fmt.Errorf("invalid nexthop: %s", nexthop) + } + } + attr := bgp.NewPathAttributeMpReachNLRI(nexthop, nlris) + attr.LinkLocalNexthop = linkLocalNexthop + return attr, nil + case *api.MpUnreachNLRIAttribute: + rf := bgp.RouteFamily(a.Family) + nlris, err := UnmarshalNLRIs(rf, a.Nlris) + if err != nil { + return nil, err + } + return bgp.NewPathAttributeMpUnreachNLRI(nlris), nil + case *api.ExtendedCommunitiesAttribute: + return unmarshalExComm(a) + case *api.As4PathAttribute: + params := make([]*bgp.As4PathParam, 0, len(a.Segments)) + for _, segment := range a.Segments { + params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) + } + return bgp.NewPathAttributeAs4Path(params), nil + case *api.As4AggregatorAttribute: + if net.ParseIP(a.Address).To4() == nil { + return nil, fmt.Errorf("invalid as4 aggregator address: %s", a.Address) + } + return bgp.NewPathAttributeAs4Aggregator(a.As, a.Address), nil + case *api.PmsiTunnelAttribute: + typ := bgp.PmsiTunnelType(a.Type) + var isLeafInfoRequired bool + if a.Flags&0x01 > 0 { + isLeafInfoRequired = true + } + var id bgp.PmsiTunnelIDInterface + switch typ { + case bgp.PMSI_TUNNEL_TYPE_INGRESS_REPL: + ip := net.IP(a.Id) + if ip.To4() == nil && ip.To16() == nil { + return nil, fmt.Errorf("invalid pmsi tunnel identifier: %s", a.Id) + } + id = bgp.NewIngressReplTunnelID(ip.String()) + default: + id = bgp.NewDefaultPmsiTunnelID(a.Id) + } + return bgp.NewPathAttributePmsiTunnel(typ, isLeafInfoRequired, a.Label, id), nil + case *api.TunnelEncapAttribute: + tlvs := make([]*bgp.TunnelEncapTLV, 0, len(a.Tlvs)) + for _, tlv := range a.Tlvs { + subTlvs := make([]bgp.TunnelEncapSubTLVInterface, 0, len(tlv.Tlvs)) + for _, an := range tlv.Tlvs { + var subTlv bgp.TunnelEncapSubTLVInterface + var subValue ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &subValue); err != nil { + return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err) + } + switch sv := subValue.Message.(type) { + case *api.TunnelEncapSubTLVEncapsulation: + subTlv = bgp.NewTunnelEncapSubTLVEncapsulation(sv.Key, sv.Cookie) + case *api.TunnelEncapSubTLVProtocol: + subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol)) + case *api.TunnelEncapSubTLVColor: + subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color) + case *api.TunnelEncapSubTLVUnknown: + subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value) + default: + return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v", subValue.Message) + } + subTlvs = append(subTlvs, subTlv) + } + tlvs = append(tlvs, bgp.NewTunnelEncapTLV(bgp.TunnelType(tlv.Type), subTlvs)) + } + return bgp.NewPathAttributeTunnelEncap(tlvs), nil + case *api.IP6ExtendedCommunitiesAttribute: + communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) + for _, an := range a.Communities { + var community bgp.ExtendedCommunityInterface + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal ipv6 extended community: %s", err) + } + switch v := value.Message.(type) { + case *api.IPv6AddressSpecificExtended: + community = bgp.NewIPv6AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) + case *api.RedirectIPv6AddressSpecificExtended: + community = bgp.NewRedirectIPv6AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) + } + if community == nil { + return nil, fmt.Errorf("invalid ipv6 extended community: %v", value.Message) + } + communities = append(communities, community) + } + return bgp.NewPathAttributeIP6ExtendedCommunities(communities), nil + + case *api.AigpAttribute: + tlvs := make([]bgp.AigpTLVInterface, 0, len(a.Tlvs)) + for _, an := range a.Tlvs { + var tlv bgp.AigpTLVInterface + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal aigp attribute tlv: %s", err) + } + switch v := value.Message.(type) { + case *api.AigpTLVIGPMetric: + tlv = bgp.NewAigpTLVIgpMetric(v.Metric) + case *api.AigpTLVUnknown: + tlv = bgp.NewAigpTLVDefault(bgp.AigpTLVType(v.Type), v.Value) + } + if tlv == nil { + return nil, fmt.Errorf("invalid aigp attribute tlv: %v", value.Message) + } + tlvs = append(tlvs, tlv) + } + return bgp.NewPathAttributeAigp(tlvs), nil + + case *api.LargeCommunitiesAttribute: + communities := make([]*bgp.LargeCommunity, 0, len(a.Communities)) + for _, c := range a.Communities { + communities = append(communities, bgp.NewLargeCommunity(c.GlobalAdmin, c.LocalData1, c.LocalData2)) + } + return bgp.NewPathAttributeLargeCommunities(communities), nil + + case *api.UnknownAttribute: + return bgp.NewPathAttributeUnknown(bgp.BGPAttrFlag(a.Flags), bgp.BGPAttrType(a.Type), a.Value), nil + } + return nil, errors.New("unknown path attribute") +} diff --git a/api/attribute_test.go b/internal/pkg/apiutil/attribute_test.go index 72b20bf1..df86427f 100644 --- a/api/attribute_test.go +++ b/internal/pkg/apiutil/attribute_test.go @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gobgpapi +package apiutil import ( "net" @@ -21,6 +21,7 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" + api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/pkg/packet/bgp" "github.com/stretchr/testify/assert" ) @@ -28,22 +29,23 @@ import ( func Test_OriginAttribute(t *testing.T) { assert := assert.New(t) - input := &OriginAttribute{ + input := &api.OriginAttribute{ Origin: 0, // IGP } - - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewOriginAttributeFromNative(n) + output := NewOriginAttributeFromNative(n.(*bgp.PathAttributeOrigin)) assert.Equal(input.Origin, output.Origin) } func Test_AsPathAttribute(t *testing.T) { assert := assert.New(t) - input := &AsPathAttribute{ - Segments: []*AsSegment{ + input := &api.AsPathAttribute{ + Segments: []*api.AsSegment{ { Type: 1, // SET Numbers: []uint32{100, 200}, @@ -55,10 +57,12 @@ func Test_AsPathAttribute(t *testing.T) { }, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewAsPathAttributeFromNative(n) + output := NewAsPathAttributeFromNative(n.(*bgp.PathAttributeAsPath)) assert.Equal(2, len(output.Segments)) assert.Equal(input.Segments, output.Segments) } @@ -66,54 +70,62 @@ func Test_AsPathAttribute(t *testing.T) { func Test_NextHopAttribute(t *testing.T) { assert := assert.New(t) - input := &NextHopAttribute{ + input := &api.NextHopAttribute{ NextHop: "192.168.0.1", } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewNextHopAttributeFromNative(n) + output := NewNextHopAttributeFromNative(n.(*bgp.PathAttributeNextHop)) assert.Equal(input.NextHop, output.NextHop) } func Test_MultiExitDiscAttribute(t *testing.T) { assert := assert.New(t) - input := &MultiExitDiscAttribute{ + input := &api.MultiExitDiscAttribute{ Med: 100, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMultiExitDiscAttributeFromNative(n) + output := NewMultiExitDiscAttributeFromNative(n.(*bgp.PathAttributeMultiExitDisc)) assert.Equal(input.Med, output.Med) } func Test_LocalPrefAttribute(t *testing.T) { assert := assert.New(t) - input := &LocalPrefAttribute{ + input := &api.LocalPrefAttribute{ LocalPref: 100, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewLocalPrefAttributeFromNative(n) + output := NewLocalPrefAttributeFromNative(n.(*bgp.PathAttributeLocalPref)) assert.Equal(input.LocalPref, output.LocalPref) } func Test_AtomicAggregateAttribute(t *testing.T) { assert := assert.New(t) - input := &AtomicAggregateAttribute{} + input := &api.AtomicAggregateAttribute{} - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewAtomicAggregateAttributeFromNative(n) + output := NewAtomicAggregateAttributeFromNative(n.(*bgp.PathAttributeAtomicAggregate)) // AtomicAggregateAttribute has no value assert.NotNil(output) } @@ -121,15 +133,17 @@ func Test_AtomicAggregateAttribute(t *testing.T) { func Test_AggregatorAttribute(t *testing.T) { assert := assert.New(t) - input := &AggregatorAttribute{ + input := &api.AggregatorAttribute{ As: 65000, Address: "1.1.1.1", } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewAggregatorAttributeFromNative(n) + output := NewAggregatorAttributeFromNative(n.(*bgp.PathAttributeAggregator)) assert.Equal(input.As, output.As) assert.Equal(input.Address, output.Address) } @@ -137,42 +151,48 @@ func Test_AggregatorAttribute(t *testing.T) { func Test_CommunitiesAttribute(t *testing.T) { assert := assert.New(t) - input := &CommunitiesAttribute{ + input := &api.CommunitiesAttribute{ Communities: []uint32{100, 200}, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewCommunitiesAttributeFromNative(n) + output := NewCommunitiesAttributeFromNative(n.(*bgp.PathAttributeCommunities)) assert.Equal(input.Communities, output.Communities) } func Test_OriginatorIdAttribute(t *testing.T) { assert := assert.New(t) - input := &OriginatorIdAttribute{ + input := &api.OriginatorIdAttribute{ Id: "1.1.1.1", } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewOriginatorIdAttributeFromNative(n) + output := NewOriginatorIdAttributeFromNative(n.(*bgp.PathAttributeOriginatorId)) assert.Equal(input.Id, output.Id) } func Test_ClusterListAttribute(t *testing.T) { assert := assert.New(t) - input := &ClusterListAttribute{ + input := &api.ClusterListAttribute{ Ids: []string{"1.1.1.1", "2.2.2.2"}, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewClusterListAttributeFromNative(n) + output := NewClusterListAttributeFromNative(n.(*bgp.PathAttributeClusterList)) assert.Equal(input.Ids, output.Ids) } @@ -180,29 +200,31 @@ func Test_MpReachNLRIAttribute_IPv4_UC(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&IPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.IPAddressPrefix{ PrefixLen: 24, Prefix: "192.168.101.0", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&IPAddressPrefix{ + a, err = ptypes.MarshalAny(&api.IPAddressPrefix{ PrefixLen: 24, Prefix: "192.168.201.0", }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv4_UC), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(2, len(output.Nlris)) @@ -217,29 +239,31 @@ func Test_MpReachNLRIAttribute_IPv6_UC(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&IPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.IPAddressPrefix{ PrefixLen: 64, Prefix: "2001:db8:1::", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&IPAddressPrefix{ + a, err = ptypes.MarshalAny(&api.IPAddressPrefix{ PrefixLen: 64, Prefix: "2001:db8:2::", }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv6_UC), NextHops: []string{"2001:db8::1", "2001:db8::2"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(2, len(output.Nlris)) @@ -254,14 +278,14 @@ func Test_MpReachNLRIAttribute_IPv4_MPLS(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&LabeledIPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.LabeledIPAddressPrefix{ Labels: []uint32{100}, PrefixLen: 24, Prefix: "192.168.101.0", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&LabeledIPAddressPrefix{ + a, err = ptypes.MarshalAny(&api.LabeledIPAddressPrefix{ Labels: []uint32{200}, PrefixLen: 24, Prefix: "192.168.201.0", @@ -269,16 +293,18 @@ func Test_MpReachNLRIAttribute_IPv4_MPLS(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv4_MPLS), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(2, len(output.Nlris)) @@ -293,14 +319,14 @@ func Test_MpReachNLRIAttribute_IPv6_MPLS(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&LabeledIPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.LabeledIPAddressPrefix{ Labels: []uint32{100}, PrefixLen: 64, Prefix: "2001:db8:1::", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&LabeledIPAddressPrefix{ + a, err = ptypes.MarshalAny(&api.LabeledIPAddressPrefix{ Labels: []uint32{200}, PrefixLen: 64, Prefix: "2001:db8:2::", @@ -308,16 +334,18 @@ func Test_MpReachNLRIAttribute_IPv6_MPLS(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv6_MPLS), NextHops: []string{"2001:db8::1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(2, len(output.Nlris)) @@ -332,27 +360,29 @@ func Test_MpReachNLRIAttribute_IPv4_ENCAP(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&EncapsulationNLRI{ + a, err := ptypes.MarshalAny(&api.EncapsulationNLRI{ Address: "192.168.101.1", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&EncapsulationNLRI{ + a, err = ptypes.MarshalAny(&api.EncapsulationNLRI{ Address: "192.168.201.1", }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv4_ENCAP), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(2, len(output.Nlris)) @@ -367,27 +397,29 @@ func Test_MpReachNLRIAttribute_IPv6_ENCAP(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&EncapsulationNLRI{ + a, err := ptypes.MarshalAny(&api.EncapsulationNLRI{ Address: "2001:db8:1::1", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&EncapsulationNLRI{ + a, err = ptypes.MarshalAny(&api.EncapsulationNLRI{ Address: "2001:db8:2::1", }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv6_ENCAP), NextHops: []string{"2001:db8::1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(2, len(output.Nlris)) @@ -402,16 +434,16 @@ func Test_MpReachNLRIAttribute_EVPN_AD_Route(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherTwoOctetAS{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherTwoOctetAS{ Admin: 65000, Assigned: 100, }) assert.Nil(err) - esi := &EthernetSegmentIdentifier{ + esi := &api.EthernetSegmentIdentifier{ Type: 0, Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, } - a, err := ptypes.MarshalAny(&EVPNEthernetAutoDiscoveryRoute{ + a, err := ptypes.MarshalAny(&api.EVPNEthernetAutoDiscoveryRoute{ Rd: rd, Esi: esi, EthernetTag: 100, @@ -420,16 +452,18 @@ func Test_MpReachNLRIAttribute_EVPN_AD_Route(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_EVPN), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -444,16 +478,16 @@ func Test_MpReachNLRIAttribute_EVPN_MAC_IP_Route(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) - esi := &EthernetSegmentIdentifier{ + esi := &api.EthernetSegmentIdentifier{ Type: 0, Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, } - a, err := ptypes.MarshalAny(&EVPNMACIPAdvertisementRoute{ + a, err := ptypes.MarshalAny(&api.EVPNMACIPAdvertisementRoute{ Rd: rd, Esi: esi, EthernetTag: 100, @@ -464,16 +498,18 @@ func Test_MpReachNLRIAttribute_EVPN_MAC_IP_Route(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_EVPN), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -488,12 +524,12 @@ func Test_MpReachNLRIAttribute_EVPN_MC_Route(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherFourOctetAS{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherFourOctetAS{ Admin: 65000, Assigned: 100, }) assert.Nil(err) - a, err := ptypes.MarshalAny(&EVPNInclusiveMulticastEthernetTagRoute{ + a, err := ptypes.MarshalAny(&api.EVPNInclusiveMulticastEthernetTagRoute{ Rd: rd, EthernetTag: 100, IpAddress: "192.168.101.1", @@ -501,16 +537,18 @@ func Test_MpReachNLRIAttribute_EVPN_MC_Route(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_EVPN), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -525,16 +563,16 @@ func Test_MpReachNLRIAttribute_EVPN_ES_Route(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) - esi := &EthernetSegmentIdentifier{ + esi := &api.EthernetSegmentIdentifier{ Type: 0, Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, } - a, err := ptypes.MarshalAny(&EVPNEthernetSegmentRoute{ + a, err := ptypes.MarshalAny(&api.EVPNEthernetSegmentRoute{ Rd: rd, Esi: esi, IpAddress: "192.168.101.1", @@ -542,16 +580,18 @@ func Test_MpReachNLRIAttribute_EVPN_ES_Route(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_EVPN), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -566,16 +606,16 @@ func Test_MpReachNLRIAttribute_EVPN_Prefix_Route(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) - esi := &EthernetSegmentIdentifier{ + esi := &api.EthernetSegmentIdentifier{ Type: 0, Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, } - a, err := ptypes.MarshalAny(&EVPNIPPrefixRoute{ + a, err := ptypes.MarshalAny(&api.EVPNIPPrefixRoute{ Rd: rd, Esi: esi, EthernetTag: 100, @@ -586,16 +626,18 @@ func Test_MpReachNLRIAttribute_EVPN_Prefix_Route(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_EVPN), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -610,12 +652,12 @@ func Test_MpReachNLRIAttribute_IPv4_VPN(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) - a, err := ptypes.MarshalAny(&LabeledVPNIPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.LabeledVPNIPAddressPrefix{ Labels: []uint32{100, 200}, Rd: rd, PrefixLen: 24, @@ -624,16 +666,18 @@ func Test_MpReachNLRIAttribute_IPv4_VPN(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv4_VPN), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -648,12 +692,12 @@ func Test_MpReachNLRIAttribute_IPv6_VPN(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) - a, err := ptypes.MarshalAny(&LabeledVPNIPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.LabeledVPNIPAddressPrefix{ Labels: []uint32{100, 200}, Rd: rd, PrefixLen: 64, @@ -662,16 +706,18 @@ func Test_MpReachNLRIAttribute_IPv6_VPN(t *testing.T) { assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_IPv6_VPN), NextHops: []string{"2001:db8::1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -686,30 +732,32 @@ func Test_MpReachNLRIAttribute_RTC_UC(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 1) - rt, err := ptypes.MarshalAny(&IPv4AddressSpecificExtended{ + rt, err := ptypes.MarshalAny(&api.IPv4AddressSpecificExtended{ IsTransitive: true, SubType: 0x02, // Route Target Address: "1.1.1.1", LocalAdmin: 100, }) assert.Nil(err) - a, err := ptypes.MarshalAny(&RouteTargetMembershipNLRI{ + a, err := ptypes.MarshalAny(&api.RouteTargetMembershipNLRI{ As: 65000, Rt: rt, }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_RTC_UC), NextHops: []string{"192.168.1.1"}, Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -724,23 +772,23 @@ func Test_MpReachNLRIAttribute_FS_IPv4_UC(t *testing.T) { assert := assert.New(t) rules := make([]*any.Any, 0, 3) - rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err := ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 1, // Destination Prefix PrefixLen: 24, Prefix: "192.168.101.0", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err = ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 2, // Source Prefix PrefixLen: 24, Prefix: "192.168.201.0", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + rule, err = ptypes.MarshalAny(&api.FlowSpecComponent{ Type: 3, // IP Protocol - Items: []*FlowSpecComponentItem{ + Items: []*api.FlowSpecComponentItem{ { Op: 0x80 | 0x01, // End, EQ Value: 6, // TCP @@ -751,22 +799,24 @@ func Test_MpReachNLRIAttribute_FS_IPv4_UC(t *testing.T) { rules = append(rules, rule) nlris := make([]*any.Any, 0, 1) - a, err := ptypes.MarshalAny(&FlowSpecNLRI{ + a, err := ptypes.MarshalAny(&api.FlowSpecNLRI{ Rules: rules, }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_FS_IPv4_UC), // NextHops: // No nexthop required Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -780,30 +830,30 @@ func Test_MpReachNLRIAttribute_FS_IPv4_UC(t *testing.T) { func Test_MpReachNLRIAttribute_FS_IPv4_VPN(t *testing.T) { assert := assert.New(t) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) rules := make([]*any.Any, 0, 3) - rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err := ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 1, // Destination Prefix PrefixLen: 24, Prefix: "192.168.101.0", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err = ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 2, // Source Prefix PrefixLen: 24, Prefix: "192.168.201.0", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + rule, err = ptypes.MarshalAny(&api.FlowSpecComponent{ Type: 3, // IP Protocol - Items: []*FlowSpecComponentItem{ + Items: []*api.FlowSpecComponentItem{ { Op: 0x80 | 0x01, // End, EQ Value: 6, // TCP @@ -814,23 +864,25 @@ func Test_MpReachNLRIAttribute_FS_IPv4_VPN(t *testing.T) { rules = append(rules, rule) nlris := make([]*any.Any, 0, 1) - a, err := ptypes.MarshalAny(&VPNFlowSpecNLRI{ + a, err := ptypes.MarshalAny(&api.VPNFlowSpecNLRI{ Rd: rd, Rules: rules, }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_FS_IPv4_VPN), // NextHops: // No nexthop required Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -845,23 +897,23 @@ func Test_MpReachNLRIAttribute_FS_IPv6_UC(t *testing.T) { assert := assert.New(t) rules := make([]*any.Any, 0, 3) - rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err := ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 1, // Destination Prefix PrefixLen: 64, Prefix: "2001:db8:1::", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err = ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 2, // Source Prefix PrefixLen: 64, Prefix: "2001:db8:2::", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + rule, err = ptypes.MarshalAny(&api.FlowSpecComponent{ Type: 3, // Next Header - Items: []*FlowSpecComponentItem{ + Items: []*api.FlowSpecComponentItem{ { Op: 0x80 | 0x01, // End, EQ Value: 6, // TCP @@ -872,22 +924,24 @@ func Test_MpReachNLRIAttribute_FS_IPv6_UC(t *testing.T) { rules = append(rules, rule) nlris := make([]*any.Any, 0, 1) - a, err := ptypes.MarshalAny(&FlowSpecNLRI{ + a, err := ptypes.MarshalAny(&api.FlowSpecNLRI{ Rules: rules, }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_FS_IPv6_UC), // NextHops: // No nexthop required Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -901,30 +955,30 @@ func Test_MpReachNLRIAttribute_FS_IPv6_UC(t *testing.T) { func Test_MpReachNLRIAttribute_FS_IPv6_VPN(t *testing.T) { assert := assert.New(t) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) rules := make([]*any.Any, 0, 3) - rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err := ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 1, // Destination Prefix PrefixLen: 64, Prefix: "2001:db8:1::", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + rule, err = ptypes.MarshalAny(&api.FlowSpecIPPrefix{ Type: 2, // Source Prefix PrefixLen: 64, Prefix: "2001:db8:2::", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + rule, err = ptypes.MarshalAny(&api.FlowSpecComponent{ Type: 3, // Next Header - Items: []*FlowSpecComponentItem{ + Items: []*api.FlowSpecComponentItem{ { Op: 0x80 | 0x01, // End, EQ Value: 6, // TCP @@ -935,23 +989,25 @@ func Test_MpReachNLRIAttribute_FS_IPv6_VPN(t *testing.T) { rules = append(rules, rule) nlris := make([]*any.Any, 0, 1) - a, err := ptypes.MarshalAny(&VPNFlowSpecNLRI{ + a, err := ptypes.MarshalAny(&api.VPNFlowSpecNLRI{ Rd: rd, Rules: rules, }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_FS_IPv6_VPN), // NextHops: // No nexthop required Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -965,28 +1021,28 @@ func Test_MpReachNLRIAttribute_FS_IPv6_VPN(t *testing.T) { func Test_MpReachNLRIAttribute_FS_L2_VPN(t *testing.T) { assert := assert.New(t) - rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + rd, err := ptypes.MarshalAny(&api.RouteDistinguisherIPAddress{ Admin: "1.1.1.1", Assigned: 100, }) assert.Nil(err) rules := make([]*any.Any, 0, 3) - rule, err := ptypes.MarshalAny(&FlowSpecMAC{ + rule, err := ptypes.MarshalAny(&api.FlowSpecMAC{ Type: 15, // Source MAC Address: "aa:bb:cc:11:22:33", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecMAC{ + rule, err = ptypes.MarshalAny(&api.FlowSpecMAC{ Type: 16, // Destination MAC Address: "dd:ee:ff:11:22:33", }) assert.Nil(err) rules = append(rules, rule) - rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + rule, err = ptypes.MarshalAny(&api.FlowSpecComponent{ Type: 21, // VLAN ID - Items: []*FlowSpecComponentItem{ + Items: []*api.FlowSpecComponentItem{ { Op: 0x80 | 0x01, // End, EQ Value: 100, @@ -997,23 +1053,25 @@ func Test_MpReachNLRIAttribute_FS_L2_VPN(t *testing.T) { rules = append(rules, rule) nlris := make([]*any.Any, 0, 1) - a, err := ptypes.MarshalAny(&VPNFlowSpecNLRI{ + a, err := ptypes.MarshalAny(&api.VPNFlowSpecNLRI{ Rd: rd, Rules: rules, }) assert.Nil(err) nlris = append(nlris, a) - input := &MpReachNLRIAttribute{ + input := &api.MpReachNLRIAttribute{ Family: uint32(bgp.RF_FS_L2_VPN), // NextHops: // No nexthop required Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpReachNLRIAttributeFromNative(n) + output := NewMpReachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpReachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(input.NextHops, output.NextHops) assert.Equal(1, len(output.Nlris)) @@ -1028,28 +1086,30 @@ func Test_MpUnreachNLRIAttribute_IPv4_UC(t *testing.T) { assert := assert.New(t) nlris := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&IPAddressPrefix{ + a, err := ptypes.MarshalAny(&api.IPAddressPrefix{ PrefixLen: 24, Prefix: "192.168.101.0", }) assert.Nil(err) nlris = append(nlris, a) - a, err = ptypes.MarshalAny(&IPAddressPrefix{ + a, err = ptypes.MarshalAny(&api.IPAddressPrefix{ PrefixLen: 24, Prefix: "192.168.201.0", }) assert.Nil(err) nlris = append(nlris, a) - input := &MpUnreachNLRIAttribute{ + input := &api.MpUnreachNLRIAttribute{ Family: uint32(bgp.RF_IPv4_UC), Nlris: nlris, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewMpUnreachNLRIAttributeFromNative(n) + output := NewMpUnreachNLRIAttributeFromNative(n.(*bgp.PathAttributeMpUnreachNLRI)) assert.Equal(input.Family, output.Family) assert.Equal(2, len(output.Nlris)) for idx, inputNLRI := range input.Nlris { @@ -1063,7 +1123,7 @@ func Test_ExtendedCommunitiesAttribute(t *testing.T) { assert := assert.New(t) communities := make([]*any.Any, 0, 19) - a, err := ptypes.MarshalAny(&TwoOctetAsSpecificExtended{ + a, err := ptypes.MarshalAny(&api.TwoOctetAsSpecificExtended{ IsTransitive: true, SubType: 0x02, // ROUTE_TARGET As: 65001, @@ -1071,7 +1131,7 @@ func Test_ExtendedCommunitiesAttribute(t *testing.T) { }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&IPv4AddressSpecificExtended{ + a, err = ptypes.MarshalAny(&api.IPv4AddressSpecificExtended{ IsTransitive: true, SubType: 0x02, // ROUTE_TARGET Address: "2.2.2.2", @@ -1079,7 +1139,7 @@ func Test_ExtendedCommunitiesAttribute(t *testing.T) { }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&FourOctetAsSpecificExtended{ + a, err = ptypes.MarshalAny(&api.FourOctetAsSpecificExtended{ IsTransitive: true, SubType: 0x02, // ROUTE_TARGET As: 65003, @@ -1087,104 +1147,106 @@ func Test_ExtendedCommunitiesAttribute(t *testing.T) { }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&ValidationExtended{ + a, err = ptypes.MarshalAny(&api.ValidationExtended{ State: 0, // VALID }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&ColorExtended{ + a, err = ptypes.MarshalAny(&api.ColorExtended{ Color: 400, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&EncapExtended{ + a, err = ptypes.MarshalAny(&api.EncapExtended{ TunnelType: 8, // VXLAN }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&DefaultGatewayExtended{ + a, err = ptypes.MarshalAny(&api.DefaultGatewayExtended{ // No value }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&OpaqueExtended{ + a, err = ptypes.MarshalAny(&api.OpaqueExtended{ IsTransitive: true, Value: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&ESILabelExtended{ + a, err = ptypes.MarshalAny(&api.ESILabelExtended{ IsSingleActive: true, Label: 500, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&ESImportRouteTarget{ + a, err = ptypes.MarshalAny(&api.ESImportRouteTarget{ EsImport: "aa:bb:cc:dd:ee:ff", }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&MacMobilityExtended{ + a, err = ptypes.MarshalAny(&api.MacMobilityExtended{ IsSticky: true, SequenceNum: 1, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&RouterMacExtended{ + a, err = ptypes.MarshalAny(&api.RouterMacExtended{ Mac: "ff:ee:dd:cc:bb:aa", }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&TrafficRateExtended{ + a, err = ptypes.MarshalAny(&api.TrafficRateExtended{ As: 65004, Rate: 100.0, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&TrafficActionExtended{ + a, err = ptypes.MarshalAny(&api.TrafficActionExtended{ Terminal: true, Sample: false, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&RedirectTwoOctetAsSpecificExtended{ + a, err = ptypes.MarshalAny(&api.RedirectTwoOctetAsSpecificExtended{ As: 65005, LocalAdmin: 500, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&RedirectIPv4AddressSpecificExtended{ + a, err = ptypes.MarshalAny(&api.RedirectIPv4AddressSpecificExtended{ Address: "6.6.6.6", LocalAdmin: 600, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&RedirectFourOctetAsSpecificExtended{ + a, err = ptypes.MarshalAny(&api.RedirectFourOctetAsSpecificExtended{ As: 65007, LocalAdmin: 700, }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&TrafficRemarkExtended{ + a, err = ptypes.MarshalAny(&api.TrafficRemarkExtended{ Dscp: 0x0a, // AF11 }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&UnknownExtended{ + a, err = ptypes.MarshalAny(&api.UnknownExtended{ Type: 0xff, // Max of uint8 Value: []byte{1, 2, 3, 4, 5, 6, 7}, }) assert.Nil(err) communities = append(communities, a) - input := &ExtendedCommunitiesAttribute{ + input := &api.ExtendedCommunitiesAttribute{ Communities: communities, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewExtendedCommunitiesAttributeFromNative(n) + output := NewExtendedCommunitiesAttributeFromNative(n.(*bgp.PathAttributeExtendedCommunities)) assert.Equal(19, len(output.Communities)) for idx, inputCommunity := range input.Communities { outputCommunity := output.Communities[idx] @@ -1196,8 +1258,8 @@ func Test_ExtendedCommunitiesAttribute(t *testing.T) { func Test_As4PathAttribute(t *testing.T) { assert := assert.New(t) - input := &As4PathAttribute{ - Segments: []*AsSegment{ + input := &api.As4PathAttribute{ + Segments: []*api.AsSegment{ { Type: 1, // SET Numbers: []uint32{100, 200}, @@ -1209,10 +1271,12 @@ func Test_As4PathAttribute(t *testing.T) { }, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewAs4PathAttributeFromNative(n) + output := NewAs4PathAttributeFromNative(n.(*bgp.PathAttributeAs4Path)) assert.Equal(2, len(output.Segments)) assert.Equal(input.Segments, output.Segments) } @@ -1220,15 +1284,17 @@ func Test_As4PathAttribute(t *testing.T) { func Test_As4AggregatorAttribute(t *testing.T) { assert := assert.New(t) - input := &As4AggregatorAttribute{ + input := &api.As4AggregatorAttribute{ As: 65000, Address: "1.1.1.1", } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewAs4AggregatorAttributeFromNative(n) + output := NewAs4AggregatorAttributeFromNative(n.(*bgp.PathAttributeAs4Aggregator)) assert.Equal(input.As, output.As) assert.Equal(input.Address, output.Address) } @@ -1236,17 +1302,19 @@ func Test_As4AggregatorAttribute(t *testing.T) { func Test_PmsiTunnelAttribute(t *testing.T) { assert := assert.New(t) - input := &PmsiTunnelAttribute{ + input := &api.PmsiTunnelAttribute{ Flags: 0x01, // IsLeafInfoRequired = true Type: 6, // INGRESS_REPL Label: 100, Id: net.ParseIP("1.1.1.1").To4(), // IngressReplTunnelID with IPv4 } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewPmsiTunnelAttributeFromNative(n) + output := NewPmsiTunnelAttributeFromNative(n.(*bgp.PathAttributePmsiTunnel)) assert.Equal(input.Flags, output.Flags) assert.Equal(input.Type, output.Type) assert.Equal(input.Label, output.Label) @@ -1257,31 +1325,31 @@ func Test_TunnelEncapAttribute(t *testing.T) { assert := assert.New(t) subTlvs := make([]*any.Any, 0, 4) - a, err := ptypes.MarshalAny(&TunnelEncapSubTLVEncapsulation{ + a, err := ptypes.MarshalAny(&api.TunnelEncapSubTLVEncapsulation{ Key: 100, Cookie: []byte{0x11, 0x22, 0x33, 0x44}, }) assert.Nil(err) subTlvs = append(subTlvs, a) - a, err = ptypes.MarshalAny(&TunnelEncapSubTLVProtocol{ + a, err = ptypes.MarshalAny(&api.TunnelEncapSubTLVProtocol{ Protocol: 200, }) assert.Nil(err) subTlvs = append(subTlvs, a) - a, err = ptypes.MarshalAny(&TunnelEncapSubTLVColor{ + a, err = ptypes.MarshalAny(&api.TunnelEncapSubTLVColor{ Color: 300, }) assert.Nil(err) subTlvs = append(subTlvs, a) - a, err = ptypes.MarshalAny(&TunnelEncapSubTLVUnknown{ + a, err = ptypes.MarshalAny(&api.TunnelEncapSubTLVUnknown{ Type: 0xff, // Max of uint8 Value: []byte{0x55, 0x66, 0x77, 0x88}, }) assert.Nil(err) subTlvs = append(subTlvs, a) - input := &TunnelEncapAttribute{ - Tlvs: []*TunnelEncapTLV{ + input := &api.TunnelEncapAttribute{ + Tlvs: []*api.TunnelEncapTLV{ { Type: 8, // VXLAN Tlvs: subTlvs, @@ -1289,10 +1357,12 @@ func Test_TunnelEncapAttribute(t *testing.T) { }, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewTunnelEncapAttributeFromNative(n) + output := NewTunnelEncapAttributeFromNative(n.(*bgp.PathAttributeTunnelEncap)) assert.Equal(1, len(output.Tlvs)) assert.Equal(input.Tlvs[0].Type, output.Tlvs[0].Type) assert.Equal(len(output.Tlvs[0].Tlvs), len(output.Tlvs[0].Tlvs)) @@ -1307,7 +1377,7 @@ func Test_IP6ExtendedCommunitiesAttribute(t *testing.T) { assert := assert.New(t) communities := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&IPv6AddressSpecificExtended{ + a, err := ptypes.MarshalAny(&api.IPv6AddressSpecificExtended{ IsTransitive: true, SubType: 0xff, // Max of uint8 Address: "2001:db8:1::1", @@ -1315,21 +1385,23 @@ func Test_IP6ExtendedCommunitiesAttribute(t *testing.T) { }) assert.Nil(err) communities = append(communities, a) - a, err = ptypes.MarshalAny(&RedirectIPv6AddressSpecificExtended{ + a, err = ptypes.MarshalAny(&api.RedirectIPv6AddressSpecificExtended{ Address: "2001:db8:2::1", LocalAdmin: 200, }) assert.Nil(err) communities = append(communities, a) - input := &IP6ExtendedCommunitiesAttribute{ + input := &api.IP6ExtendedCommunitiesAttribute{ Communities: communities, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewIP6ExtendedCommunitiesAttributeFromNative(n) + output := NewIP6ExtendedCommunitiesAttributeFromNative(n.(*bgp.PathAttributeIP6ExtendedCommunities)) assert.Equal(2, len(output.Communities)) for idx, inputCommunity := range input.Communities { outputCommunity := output.Communities[idx] @@ -1342,26 +1414,28 @@ func Test_AigpAttribute(t *testing.T) { assert := assert.New(t) tlvs := make([]*any.Any, 0, 2) - a, err := ptypes.MarshalAny(&AigpTLVIGPMetric{ + a, err := ptypes.MarshalAny(&api.AigpTLVIGPMetric{ Metric: 50, }) assert.Nil(err) tlvs = append(tlvs, a) - a, err = ptypes.MarshalAny(&AigpTLVUnknown{ + a, err = ptypes.MarshalAny(&api.AigpTLVUnknown{ Type: 0xff, // Max of uint8 Value: []byte{0x11, 0x22, 0x33, 0x44}, }) assert.Nil(err) tlvs = append(tlvs, a) - input := &AigpAttribute{ + input := &api.AigpAttribute{ Tlvs: tlvs, } - n, err := input.ToNative() + a, err = ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewAigpAttributeFromNative(n) + output := NewAigpAttributeFromNative(n.(*bgp.PathAttributeAigp)) assert.Equal(2, len(output.Tlvs)) for idx, inputTlv := range input.Tlvs { outputTlv := output.Tlvs[idx] @@ -1373,8 +1447,8 @@ func Test_AigpAttribute(t *testing.T) { func Test_LargeCommunitiesAttribute(t *testing.T) { assert := assert.New(t) - input := &LargeCommunitiesAttribute{ - Communities: []*LargeCommunity{ + input := &api.LargeCommunitiesAttribute{ + Communities: []*api.LargeCommunity{ { GlobalAdmin: 65001, LocalData1: 100, @@ -1388,10 +1462,12 @@ func Test_LargeCommunitiesAttribute(t *testing.T) { }, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewLargeCommunitiesAttributeFromNative(n) + output := NewLargeCommunitiesAttributeFromNative(n.(*bgp.PathAttributeLargeCommunities)) assert.Equal(2, len(output.Communities)) assert.Equal(input.Communities, output.Communities) } @@ -1399,16 +1475,18 @@ func Test_LargeCommunitiesAttribute(t *testing.T) { func Test_UnknownAttribute(t *testing.T) { assert := assert.New(t) - input := &UnknownAttribute{ + input := &api.UnknownAttribute{ Flags: (1 << 6) | (1 << 7), // OPTIONAL and TRANSITIVE Type: 0xff, Value: []byte{0x11, 0x22, 0x33, 0x44}, } - n, err := input.ToNative() + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalAttribute(a) assert.Nil(err) - output := NewUnknownAttributeFromNative(n) + output := NewUnknownAttributeFromNative(n.(*bgp.PathAttributeUnknown)) assert.Equal(input.Flags, output.Flags) assert.Equal(input.Type, output.Type) assert.Equal(input.Value, output.Value) diff --git a/internal/pkg/apiutil/capability.go b/internal/pkg/apiutil/capability.go new file mode 100644 index 00000000..0e3b4c0b --- /dev/null +++ b/internal/pkg/apiutil/capability.go @@ -0,0 +1,244 @@ +// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apiutil + +import ( + "fmt" + + proto "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + "github.com/golang/protobuf/ptypes/any" + api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/pkg/packet/bgp" +) + +func NewMultiProtocolCapability(a *bgp.CapMultiProtocol) *api.MultiProtocolCapability { + return &api.MultiProtocolCapability{ + Family: api.Family(a.CapValue), + } +} + +func NewRouteRefreshCapability(a *bgp.CapRouteRefresh) *api.RouteRefreshCapability { + return &api.RouteRefreshCapability{} +} + +func NewCarryingLabelInfoCapability(a *bgp.CapCarryingLabelInfo) *api.CarryingLabelInfoCapability { + return &api.CarryingLabelInfoCapability{} +} + +func NewExtendedNexthopCapability(a *bgp.CapExtendedNexthop) *api.ExtendedNexthopCapability { + tuples := make([]*api.ExtendedNexthopCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &api.ExtendedNexthopCapabilityTuple{ + NlriFamily: api.Family(bgp.AfiSafiToRouteFamily(t.NLRIAFI, uint8(t.NLRISAFI))), + NexthopFamily: api.Family(bgp.AfiSafiToRouteFamily(t.NexthopAFI, bgp.SAFI_UNICAST)), + }) + } + return &api.ExtendedNexthopCapability{ + Tuples: tuples, + } +} + +func NewGracefulRestartCapability(a *bgp.CapGracefulRestart) *api.GracefulRestartCapability { + tuples := make([]*api.GracefulRestartCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &api.GracefulRestartCapabilityTuple{ + Family: api.Family(bgp.AfiSafiToRouteFamily(t.AFI, uint8(t.SAFI))), + Flags: uint32(t.Flags), + }) + } + return &api.GracefulRestartCapability{ + Flags: uint32(a.Flags), + Time: uint32(a.Time), + Tuples: tuples, + } +} + +func NewFourOctetASNumberCapability(a *bgp.CapFourOctetASNumber) *api.FourOctetASNumberCapability { + return &api.FourOctetASNumberCapability{ + As: a.CapValue, + } +} + +func NewAddPathCapability(a *bgp.CapAddPath) *api.AddPathCapability { + tuples := make([]*api.AddPathCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &api.AddPathCapabilityTuple{ + Family: api.Family(t.RouteFamily), + Mode: api.AddPathMode(t.Mode), + }) + } + return &api.AddPathCapability{ + Tuples: tuples, + } +} + +func NewEnhancedRouteRefreshCapability(a *bgp.CapEnhancedRouteRefresh) *api.EnhancedRouteRefreshCapability { + return &api.EnhancedRouteRefreshCapability{} +} + +func NewLongLivedGracefulRestartCapability(a *bgp.CapLongLivedGracefulRestart) *api.LongLivedGracefulRestartCapability { + tuples := make([]*api.LongLivedGracefulRestartCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &api.LongLivedGracefulRestartCapabilityTuple{ + Family: api.Family(bgp.AfiSafiToRouteFamily(t.AFI, uint8(t.SAFI))), + Flags: uint32(t.Flags), + Time: t.RestartTime, + }) + } + return &api.LongLivedGracefulRestartCapability{ + Tuples: tuples, + } +} + +func NewRouteRefreshCiscoCapability(a *bgp.CapRouteRefreshCisco) *api.RouteRefreshCiscoCapability { + return &api.RouteRefreshCiscoCapability{} +} + +func NewUnknownCapability(a *bgp.CapUnknown) *api.UnknownCapability { + return &api.UnknownCapability{ + Code: uint32(a.CapCode), + Value: a.CapValue, + } +} + +func MarshalCapability(value bgp.ParameterCapabilityInterface) (*any.Any, error) { + var m proto.Message + switch n := value.(type) { + case *bgp.CapMultiProtocol: + m = NewMultiProtocolCapability(n) + case *bgp.CapRouteRefresh: + m = NewRouteRefreshCapability(n) + case *bgp.CapCarryingLabelInfo: + m = NewCarryingLabelInfoCapability(n) + case *bgp.CapExtendedNexthop: + m = NewExtendedNexthopCapability(n) + case *bgp.CapGracefulRestart: + m = NewGracefulRestartCapability(n) + case *bgp.CapFourOctetASNumber: + m = NewFourOctetASNumberCapability(n) + case *bgp.CapAddPath: + m = NewAddPathCapability(n) + case *bgp.CapEnhancedRouteRefresh: + m = NewEnhancedRouteRefreshCapability(n) + case *bgp.CapLongLivedGracefulRestart: + m = NewLongLivedGracefulRestartCapability(n) + case *bgp.CapRouteRefreshCisco: + m = NewRouteRefreshCiscoCapability(n) + case *bgp.CapUnknown: + m = NewUnknownCapability(n) + default: + return nil, fmt.Errorf("invalid capability type to marshal: %+v", value) + } + return ptypes.MarshalAny(m) +} + +func MarshalCapabilities(values []bgp.ParameterCapabilityInterface) ([]*any.Any, error) { + caps := make([]*any.Any, 0, len(values)) + for _, value := range values { + a, err := MarshalCapability(value) + if err != nil { + return nil, err + } + caps = append(caps, a) + } + return caps, nil +} + +func unmarshalCapability(a *any.Any) (bgp.ParameterCapabilityInterface, error) { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(a, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal capability: %s", err) + } + switch a := value.Message.(type) { + case *api.MultiProtocolCapability: + return bgp.NewCapMultiProtocol(bgp.RouteFamily(a.Family)), nil + case *api.RouteRefreshCapability: + return bgp.NewCapRouteRefresh(), nil + case *api.CarryingLabelInfoCapability: + return bgp.NewCapCarryingLabelInfo(), nil + case *api.ExtendedNexthopCapability: + tuples := make([]*bgp.CapExtendedNexthopTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + var nhAfi uint16 + switch t.NexthopFamily { + case api.Family_IPv4: + nhAfi = bgp.AFI_IP + case api.Family_IPv6: + nhAfi = bgp.AFI_IP6 + default: + return nil, fmt.Errorf("invalid address family for nexthop afi in extended nexthop capability: %s", t.NexthopFamily) + } + tuples = append(tuples, bgp.NewCapExtendedNexthopTuple(bgp.RouteFamily(t.NlriFamily), nhAfi)) + } + return bgp.NewCapExtendedNexthop(tuples), nil + case *api.GracefulRestartCapability: + tuples := make([]*bgp.CapGracefulRestartTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + var forward bool + if t.Flags&0x80 > 0 { + forward = true + } + tuples = append(tuples, bgp.NewCapGracefulRestartTuple(bgp.RouteFamily(t.Family), forward)) + } + var restarting bool + if a.Flags&0x08 > 0 { + restarting = true + } + var notification bool + if a.Flags&0x04 > 0 { + notification = true + } + return bgp.NewCapGracefulRestart(restarting, notification, uint16(a.Time), tuples), nil + case *api.FourOctetASNumberCapability: + return bgp.NewCapFourOctetASNumber(a.As), nil + case *api.AddPathCapability: + tuples := make([]*bgp.CapAddPathTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, bgp.NewCapAddPathTuple(bgp.RouteFamily(t.Family), bgp.BGPAddPathMode(t.Mode))) + } + return bgp.NewCapAddPath(tuples), nil + case *api.EnhancedRouteRefreshCapability: + return bgp.NewCapEnhancedRouteRefresh(), nil + case *api.LongLivedGracefulRestartCapability: + tuples := make([]*bgp.CapLongLivedGracefulRestartTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + var forward bool + if t.Flags&0x80 > 0 { + forward = true + } + tuples = append(tuples, bgp.NewCapLongLivedGracefulRestartTuple(bgp.RouteFamily(t.Family), forward, t.Time)) + } + return bgp.NewCapLongLivedGracefulRestart(tuples), nil + case *api.RouteRefreshCiscoCapability: + return bgp.NewCapRouteRefreshCisco(), nil + case *api.UnknownCapability: + return bgp.NewCapUnknown(bgp.BGPCapabilityCode(a.Code), a.Value), nil + } + return nil, fmt.Errorf("invalid capability type to unmarshal: %s", a.TypeUrl) +} + +func UnmarshalCapabilities(values []*any.Any) ([]bgp.ParameterCapabilityInterface, error) { + caps := make([]bgp.ParameterCapabilityInterface, 0, len(values)) + for _, value := range values { + c, err := unmarshalCapability(value) + if err != nil { + return nil, err + } + caps = append(caps, c) + } + return caps, nil +} diff --git a/internal/pkg/apiutil/capability_test.go b/internal/pkg/apiutil/capability_test.go new file mode 100644 index 00000000..0872ed58 --- /dev/null +++ b/internal/pkg/apiutil/capability_test.go @@ -0,0 +1,251 @@ +// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apiutil + +import ( + "testing" + + "github.com/golang/protobuf/ptypes" + api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/pkg/packet/bgp" + "github.com/stretchr/testify/assert" +) + +func Test_MultiProtocolCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.MultiProtocolCapability{ + Family: api.Family_IPv4, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + c := n.(*bgp.CapMultiProtocol) + assert.Equal(bgp.RF_IPv4_UC, c.CapValue) + + output := NewMultiProtocolCapability(c) + assert.Equal(input, output) +} + +func Test_RouteRefreshCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.RouteRefreshCapability{} + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + output := NewRouteRefreshCapability(n.(*bgp.CapRouteRefresh)) + assert.Equal(input, output) +} + +func Test_CarryingLabelInfoCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.CarryingLabelInfoCapability{} + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + output := NewCarryingLabelInfoCapability(n.(*bgp.CapCarryingLabelInfo)) + assert.Equal(input, output) +} + +func Test_ExtendedNexthopCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.ExtendedNexthopCapability{ + Tuples: []*api.ExtendedNexthopCapabilityTuple{ + { + NlriFamily: api.Family_IPv4, + NexthopFamily: api.Family_IPv6, + }, + }, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + c := n.(*bgp.CapExtendedNexthop) + assert.Equal(1, len(c.Tuples)) + assert.Equal(uint16(bgp.AFI_IP), c.Tuples[0].NLRIAFI) + assert.Equal(uint16(bgp.SAFI_UNICAST), c.Tuples[0].NLRISAFI) + assert.Equal(uint16(bgp.AFI_IP6), c.Tuples[0].NexthopAFI) + + output := NewExtendedNexthopCapability(c) + assert.Equal(input, output) +} + +func Test_GracefulRestartCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.GracefulRestartCapability{ + Flags: 0x08 | 0x04, // restarting|notification + Time: 90, + Tuples: []*api.GracefulRestartCapabilityTuple{ + { + Family: api.Family_IPv4, + Flags: 0x80, // forward + }, + }, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + c := n.(*bgp.CapGracefulRestart) + assert.Equal(1, len(c.Tuples)) + assert.Equal(uint8(0x08|0x04), c.Flags) + assert.Equal(uint16(90), c.Time) + assert.Equal(uint16(bgp.AFI_IP), c.Tuples[0].AFI) + assert.Equal(uint8(bgp.SAFI_UNICAST), c.Tuples[0].SAFI) + assert.Equal(uint8(0x80), c.Tuples[0].Flags) + + output := NewGracefulRestartCapability(c) + assert.Equal(input, output) +} + +func Test_FourOctetASNumberCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.FourOctetASNumberCapability{ + As: 100, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + c := n.(*bgp.CapFourOctetASNumber) + assert.Equal(uint32(100), c.CapValue) + + output := NewFourOctetASNumberCapability(c) + assert.Equal(input, output) +} + +func Test_AddPathCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.AddPathCapability{ + Tuples: []*api.AddPathCapabilityTuple{ + { + Family: api.Family_IPv4, + Mode: api.AddPathMode_MODE_BOTH, + }, + }, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + c := n.(*bgp.CapAddPath) + assert.Equal(1, len(c.Tuples)) + assert.Equal(bgp.RF_IPv4_UC, c.Tuples[0].RouteFamily) + assert.Equal(bgp.BGP_ADD_PATH_BOTH, c.Tuples[0].Mode) + + output := NewAddPathCapability(c) + assert.Equal(input, output) +} + +func Test_EnhancedRouteRefreshCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.EnhancedRouteRefreshCapability{} + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + output := NewEnhancedRouteRefreshCapability(n.(*bgp.CapEnhancedRouteRefresh)) + assert.Equal(input, output) +} + +func Test_LongLivedGracefulRestartCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.LongLivedGracefulRestartCapability{ + Tuples: []*api.LongLivedGracefulRestartCapabilityTuple{ + { + Family: api.Family_IPv4, + Flags: 0x80, // forward + Time: 90, + }, + }, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + c := n.(*bgp.CapLongLivedGracefulRestart) + assert.Equal(1, len(c.Tuples)) + assert.Equal(uint16(bgp.AFI_IP), c.Tuples[0].AFI) + assert.Equal(uint8(bgp.SAFI_UNICAST), c.Tuples[0].SAFI) + assert.Equal(uint8(0x80), c.Tuples[0].Flags) + assert.Equal(uint32(90), c.Tuples[0].RestartTime) + + output := NewLongLivedGracefulRestartCapability(c) + assert.Equal(input, output) +} + +func Test_RouteRefreshCiscoCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.RouteRefreshCiscoCapability{} + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + output := NewRouteRefreshCiscoCapability(n.(*bgp.CapRouteRefreshCisco)) + assert.Equal(input, output) +} + +func Test_UnknownCapability(t *testing.T) { + assert := assert.New(t) + + input := &api.UnknownCapability{ + Code: 0xff, + Value: []byte{0x11, 0x22, 0x33, 0x44}, + } + + a, err := ptypes.MarshalAny(input) + assert.Nil(err) + n, err := unmarshalCapability(a) + assert.Nil(err) + + c := n.(*bgp.CapUnknown) + assert.Equal(bgp.BGPCapabilityCode(0xff), c.CapCode) + assert.Equal([]byte{0x11, 0x22, 0x33, 0x44}, c.CapValue) + + output := NewUnknownCapability(c) + assert.Equal(input, output) +} diff --git a/api/util.go b/internal/pkg/apiutil/util.go index c06484c0..45cf1a04 100644 --- a/api/util.go +++ b/internal/pkg/apiutil/util.go @@ -13,34 +13,58 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gobgpapi +package apiutil import ( "encoding/json" "net" "time" + api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/pkg/packet/bgp" ) -func getNLRI(family bgp.RouteFamily, buf []byte) (bgp.AddrPrefixInterface, error) { - afi, safi := bgp.RouteFamilyToAfiSafi(family) - nlri, err := bgp.NewPrefixFromRouteFamily(afi, safi) - if err != nil { - return nil, err - } - if err := nlri.DecodeFromBytes(buf); err != nil { - return nil, err - } - return nlri, nil +// workaround. This for the json format compatibility. Once we update senario tests, we can remove this. +type Path struct { + Nlri bgp.AddrPrefixInterface `json:"nlri"` + Age int64 `json:"age"` + Best bool `json:"best"` + Attrs []bgp.PathAttributeInterface `json:"attrs"` + Stale bool `json:"stale"` + Withdrawal bool `json:"withdrawal,omitempty"` + SourceID net.IP `json:"source-id,omitempty"` + NeighborIP net.IP `json:"neighbor-ip,omitempty"` +} + +type Destination struct { + Paths []*Path } func (d *Destination) MarshalJSON() ([]byte, error) { return json.Marshal(d.Paths) } -func NewPath(nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, age time.Time) *Path { - return &Path{ +func NewDestination(dst *api.Destination) *Destination { + l := make([]*Path, 0, len(dst.Paths)) + for _, p := range dst.Paths { + nlri, _ := GetNativeNlri(p) + attrs, _ := GetNativePathAttributes(p) + l = append(l, &Path{ + Nlri: nlri, + Age: p.Age, + Best: p.Best, + Attrs: attrs, + Stale: p.Stale, + Withdrawal: p.IsWithdraw, + SourceID: net.ParseIP(p.SourceId), + NeighborIP: net.ParseIP(p.NeighborIp), + }) + } + return &Destination{Paths: l} +} + +func NewPath(nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, age time.Time) *api.Path { + return &api.Path{ AnyNlri: MarshalNLRI(nlri), AnyPattrs: MarshalPathAttributes(attrs), Age: age.Unix(), @@ -50,45 +74,26 @@ func NewPath(nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttr } } -func (p *Path) MarshalJSON() ([]byte, error) { - nlri, err := p.GetNativeNlri() +func getNLRI(family bgp.RouteFamily, buf []byte) (bgp.AddrPrefixInterface, error) { + afi, safi := bgp.RouteFamilyToAfiSafi(family) + nlri, err := bgp.NewPrefixFromRouteFamily(afi, safi) if err != nil { return nil, err } - attrs, err := p.GetNativePathAttributes() - if err != nil { + if err := nlri.DecodeFromBytes(buf); err != nil { return nil, err } - - return json.Marshal(struct { - Nlri bgp.AddrPrefixInterface `json:"nlri"` - Age int64 `json:"age"` - Best bool `json:"best"` - Attrs []bgp.PathAttributeInterface `json:"attrs"` - Stale bool `json:"stale"` - Withdrawal bool `json:"withdrawal,omitempty"` - SourceID net.IP `json:"source-id,omitempty"` - NeighborIP net.IP `json:"neighbor-ip,omitempty"` - }{ - Nlri: nlri, - Age: p.Age, - Best: p.Best, - Attrs: attrs, - Stale: p.Stale, - Withdrawal: p.IsWithdraw, - SourceID: net.ParseIP(p.SourceId), - NeighborIP: net.ParseIP(p.NeighborIp), - }) + return nlri, nil } -func (p *Path) GetNativeNlri() (bgp.AddrPrefixInterface, error) { +func GetNativeNlri(p *api.Path) (bgp.AddrPrefixInterface, error) { if len(p.Nlri) > 0 { return getNLRI(bgp.RouteFamily(p.Family), p.Nlri) } return UnmarshalNLRI(bgp.RouteFamily(p.Family), p.AnyNlri) } -func (p *Path) GetNativePathAttributes() ([]bgp.PathAttributeInterface, error) { +func GetNativePathAttributes(p *api.Path) ([]bgp.PathAttributeInterface, error) { pattrsLen := len(p.Pattrs) if pattrsLen > 0 { pattrs := make([]bgp.PathAttributeInterface, 0, pattrsLen) diff --git a/internal/pkg/client/client.go b/internal/pkg/client/client.go index 28adfd62..61d0ab27 100644 --- a/internal/pkg/client/client.go +++ b/internal/pkg/client/client.go @@ -27,6 +27,7 @@ import ( "google.golang.org/grpc" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/internal/pkg/config" "github.com/osrg/gobgp/pkg/packet/bgp" "github.com/osrg/gobgp/pkg/server" @@ -263,7 +264,7 @@ func (cli *Client) getRIB(resource api.Resource, name string, family bgp.RouteFa } return nil, err } - nlri, err := p.GetNativeNlri() + nlri, err := apiutil.GetNativeNlri(p) if err != nil { return nil, err } @@ -272,7 +273,7 @@ func (cli *Client) getRIB(resource api.Resource, name string, family bgp.RouteFa } dstList := make([]*api.Destination, 0, len(pathMap)) for _, pathList := range pathMap { - nlri, _ := pathList[0].GetNativeNlri() + nlri, _ := apiutil.GetNativeNlri(pathList[0]) dstList = append(dstList, &api.Destination{ Prefix: nlri.String(), Paths: pathList, @@ -454,10 +455,10 @@ func (cli *Client) AddVRF(name string, id int, rd bgp.RouteDistinguisherInterfac arg := &api.AddVrfRequest{ Vrf: &api.Vrf{ Name: name, - Rd: api.MarshalRD(rd), + Rd: apiutil.MarshalRD(rd), Id: uint32(id), - ImportRt: api.MarshalRTs(im), - ExportRt: api.MarshalRTs(ex), + ImportRt: apiutil.MarshalRTs(im), + ExportRt: apiutil.MarshalRTs(ex), }, } _, err := cli.cli.AddVrf(context.Background(), arg) diff --git a/pkg/server/grpc_server.go b/pkg/server/grpc_server.go index 37b7c57b..2a74e154 100644 --- a/pkg/server/grpc_server.go +++ b/pkg/server/grpc_server.go @@ -34,6 +34,7 @@ import ( "google.golang.org/grpc" api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/internal/pkg/config" "github.com/osrg/gobgp/internal/pkg/table" "github.com/osrg/gobgp/internal/pkg/zebra" @@ -260,11 +261,11 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *api.Peer { if pconf.Transport.State.LocalAddress != "" { localAddress = pconf.Transport.State.LocalAddress } - remoteCap, err := api.MarshalCapabilities(pconf.State.RemoteCapabilityList) + remoteCap, err := apiutil.MarshalCapabilities(pconf.State.RemoteCapabilityList) if err != nil { return nil } - localCap, err := api.MarshalCapabilities(pconf.State.LocalCapabilityList) + localCap, err := apiutil.MarshalCapabilities(pconf.State.LocalCapabilityList) if err != nil { return nil } @@ -494,11 +495,11 @@ func toPathAPI(binNlri []byte, binPattrs [][]byte, anyNlri *any.Any, anyPattrs [ func ToPathApi(path *table.Path, v *table.Validation) *api.Path { nlri := path.GetNlri() - anyNlri := api.MarshalNLRI(nlri) + anyNlri := apiutil.MarshalNLRI(nlri) if path.IsWithdraw { return toPathAPI(nil, nil, anyNlri, nil, path, v) } - anyPattrs := api.MarshalPathAttributes(path.GetPathAttrs()) + anyPattrs := apiutil.MarshalPathAttributes(path.GetPathAttrs()) return toPathAPI(nil, nil, anyNlri, anyPattrs, path, v) } @@ -853,13 +854,13 @@ func (s *Server) api2PathList(resource api.Resource, ApiPathList []*api.Path) ([ } } - nlri, err := path.GetNativeNlri() + nlri, err := apiutil.GetNativeNlri(path) if err != nil { return nil, err } nlri.SetPathIdentifier(path.Identifier) - attrList, err := path.GetNativePathAttributes() + attrList, err := apiutil.GetNativePathAttributes(path) if err != nil { return nil, err } @@ -1103,10 +1104,10 @@ func (s *Server) GetVrf(ctx context.Context, arg *api.GetVrfRequest) (*api.GetVr toApi := func(v *table.Vrf) *api.Vrf { return &api.Vrf{ Name: v.Name, - Rd: api.MarshalRD(v.Rd), + Rd: apiutil.MarshalRD(v.Rd), Id: v.Id, - ImportRt: api.MarshalRTs(v.ImportRt), - ExportRt: api.MarshalRTs(v.ExportRt), + ImportRt: apiutil.MarshalRTs(v.ImportRt), + ExportRt: apiutil.MarshalRTs(v.ExportRt), } } vrfs := s.bgpServer.GetVrf() @@ -1121,15 +1122,15 @@ func (s *Server) AddVrf(ctx context.Context, arg *api.AddVrfRequest) (r *api.Add if arg == nil || arg.Vrf == nil { return nil, fmt.Errorf("invalid request") } - rd, err := api.UnmarshalRD(arg.Vrf.Rd) + rd, err := apiutil.UnmarshalRD(arg.Vrf.Rd) if err != nil { return nil, err } - im, err := api.UnmarshalRTs(arg.Vrf.ImportRt) + im, err := apiutil.UnmarshalRTs(arg.Vrf.ImportRt) if err != nil { return nil, err } - ex, err := api.UnmarshalRTs(arg.Vrf.ExportRt) + ex, err := apiutil.UnmarshalRTs(arg.Vrf.ExportRt) if err != nil { return nil, err } @@ -1290,11 +1291,11 @@ func NewNeighborFromAPIStruct(a *api.Peer) (*config.Neighbor, error) { pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_REPLACE } - localCaps, err := api.UnmarshalCapabilities(a.Conf.LocalCap) + localCaps, err := apiutil.UnmarshalCapabilities(a.Conf.LocalCap) if err != nil { return nil, err } - remoteCaps, err := api.UnmarshalCapabilities(a.Conf.RemoteCap) + remoteCaps, err := apiutil.UnmarshalCapabilities(a.Conf.RemoteCap) if err != nil { return nil, err } |