diff options
-rw-r--r-- | api/attribute.go | 1306 | ||||
-rw-r--r-- | api/attribute.pb.go | 2086 | ||||
-rw-r--r-- | api/attribute.proto | 504 | ||||
-rw-r--r-- | api/attribute_test.go | 1416 | ||||
-rw-r--r-- | api/gobgp.pb.go | 73 | ||||
-rw-r--r-- | tools/spell-check/ignore.txt | 2 |
6 files changed, 5387 insertions, 0 deletions
diff --git a/api/attribute.go b/api/attribute.go new file mode 100644 index 00000000..a4f5734e --- /dev/null +++ b/api/attribute.go @@ -0,0 +1,1306 @@ +// 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" + "net" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + "github.com/golang/protobuf/ptypes/any" + log "github.com/sirupsen/logrus" + + "github.com/osrg/gobgp/packet/bgp" +) + +func NewOriginAttributeFromNative(a *bgp.PathAttributeOrigin) *OriginAttribute { + return &OriginAttribute{ + Origin: uint32(a.Value), + } +} + +func (a *OriginAttribute) ToNative() (*bgp.PathAttributeOrigin, error) { + return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil +} + +func NewAsPathAttributeFromNative(a *bgp.PathAttributeAsPath) *AsPathAttribute { + segments := make([]*AsSegment, 0, len(a.Value)) + for _, param := range a.Value { + segments = append(segments, &AsSegment{ + Type: uint32(param.GetType()), + Numbers: param.GetAS(), + }) + } + return &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{ + 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{ + Med: a.Value, + } +} + +func (a *MultiExitDiscAttribute) ToNative() (*bgp.PathAttributeMultiExitDisc, error) { + return bgp.NewPathAttributeMultiExitDisc(a.Med), nil +} + +func NewLocalPrefAttributeFromNative(a *bgp.PathAttributeLocalPref) *LocalPrefAttribute { + return &LocalPrefAttribute{ + LocalPref: a.Value, + } +} + +func (a *LocalPrefAttribute) ToNative() (*bgp.PathAttributeLocalPref, error) { + return bgp.NewPathAttributeLocalPref(a.LocalPref), nil +} + +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{ + 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{ + Communities: a.Value, + } +} + +func (a *CommunitiesAttribute) ToNative() (*bgp.PathAttributeCommunities, error) { + return bgp.NewPathAttributeCommunities(a.Communities), nil +} + +func NewOriginatorIdAttributeFromNative(a *bgp.PathAttributeOriginatorId) *OriginatorIdAttribute { + return &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 { + ids := make([]string, 0, len(a.Value)) + for _, id := range a.Value { + ids = append(ids, id.String()) + } + return &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{ + Admin: uint32(v.Admin), + Assigned: v.Assigned, + } + case *bgp.RouteDistinguisherIPAddressAS: + r = &RouteDistinguisherIPAddress{ + Admin: v.Admin.String(), + Assigned: uint32(v.Assigned), + } + case *bgp.RouteDistinguisherFourOctetAS: + r = &RouteDistinguisherFourOctetAS{ + Admin: v.Admin, + Assigned: uint32(v.Assigned), + } + default: + return nil + } + a, _ := ptypes.MarshalAny(r) + return a +} + +func UnmarshalRD(a *any.Any) (bgp.RouteDistinguisherInterface, error) { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(a, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) + } + switch v := value.Message.(type) { + case *RouteDistinguisherTwoOctetAS: + return bgp.NewRouteDistinguisherTwoOctetAS(uint16(v.Admin), v.Assigned), nil + case *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: + 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{ + Type: uint32(a.Type), + Value: a.Value, + } +} + +func (a *EthernetSegmentIdentifier) ToNative() (*bgp.EthernetSegmentIdentifier, error) { + return &bgp.EthernetSegmentIdentifier{ + Type: bgp.ESIType(a.Type), + Value: a.Value, + }, nil +} + +func MarshalFlowSpecRules(values []bgp.FlowSpecComponentInterface) []*any.Any { + rules := make([]*any.Any, 0, len(values)) + for _, value := range values { + var rule proto.Message + switch v := value.(type) { + case *bgp.FlowSpecDestinationPrefix: + rule = &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{ + 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{ + 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{ + 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{ + Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_MAC), + Address: v.Mac.String(), + } + case *bgp.FlowSpecDestinationMac: + rule = &FlowSpecMAC{ + Type: uint32(bgp.FLOW_SPEC_TYPE_DST_MAC), + Address: v.Mac.String(), + } + case *bgp.FlowSpecComponent: + items := make([]*FlowSpecComponentItem, 0, len(v.Items)) + for _, i := range v.Items { + items = append(items, &FlowSpecComponentItem{ + Op: uint32(i.Op), + Value: i.Value, + }) + } + rule = &FlowSpecComponent{ + Type: uint32(v.Type()), + Items: items, + } + } + a, _ := ptypes.MarshalAny(rule) + rules = append(rules, a) + } + return rules +} + +func UnmarshalFlowSpecRules(values []*any.Any) ([]bgp.FlowSpecComponentInterface, error) { + rules := make([]bgp.FlowSpecComponentInterface, 0, len(values)) + for _, an := range values { + var rule bgp.FlowSpecComponentInterface + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal flow spec component: %s", err) + } + switch v := value.Message.(type) { + case *FlowSpecIPPrefix: + typ := bgp.BGPFlowSpecType(v.Type) + isIPv4 := net.ParseIP(v.Prefix).To4() != nil + switch { + case typ == bgp.FLOW_SPEC_TYPE_DST_PREFIX && isIPv4: + rule = bgp.NewFlowSpecDestinationPrefix(bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix)) + case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && isIPv4: + rule = bgp.NewFlowSpecSourcePrefix(bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix)) + case typ == bgp.FLOW_SPEC_TYPE_DST_PREFIX && !isIPv4: + rule = bgp.NewFlowSpecDestinationPrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) + case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && !isIPv4: + rule = bgp.NewFlowSpecSourcePrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) + } + case *FlowSpecMAC: + typ := bgp.BGPFlowSpecType(v.Type) + mac, err := net.ParseMAC(v.Address) + if err != nil { + return nil, fmt.Errorf("invalid mac address for %s flow spec component: %s", typ.String(), v.Address) + } + switch typ { + case bgp.FLOW_SPEC_TYPE_SRC_MAC: + rule = bgp.NewFlowSpecSourceMac(mac) + case bgp.FLOW_SPEC_TYPE_DST_MAC: + rule = bgp.NewFlowSpecDestinationMac(mac) + } + case *FlowSpecComponent: + items := make([]*bgp.FlowSpecComponentItem, 0, len(v.Items)) + for _, item := range v.Items { + items = append(items, bgp.NewFlowSpecComponentItem(uint8(item.Op), item.Value)) + } + rule = bgp.NewFlowSpecComponent(bgp.BGPFlowSpecType(v.Type), items) + } + if rule == nil { + return nil, fmt.Errorf("invalid flow spec component: %v", value.Message) + } + rules = append(rules, rule) + } + return rules, nil +} + +func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any { + var nlri proto.Message + + switch v := value.(type) { + case *bgp.IPAddrPrefix: + nlri = &IPAddressPrefix{ + PrefixLen: uint32(v.Length), + Prefix: v.Prefix.String(), + } + case *bgp.IPv6AddrPrefix: + nlri = &IPAddressPrefix{ + PrefixLen: uint32(v.Length), + Prefix: v.Prefix.String(), + } + case *bgp.LabeledIPAddrPrefix: + nlri = &LabeledIPAddressPrefix{ + Labels: v.Labels.Labels, + PrefixLen: uint32(v.IPPrefixLen()), + Prefix: v.Prefix.String(), + } + case *bgp.LabeledIPv6AddrPrefix: + nlri = &LabeledIPAddressPrefix{ + Labels: v.Labels.Labels, + PrefixLen: uint32(v.IPPrefixLen()), + Prefix: v.Prefix.String(), + } + case *bgp.EncapNLRI: + nlri = &EncapsulationNLRI{ + Address: v.String(), + } + case *bgp.Encapv6NLRI: + nlri = &EncapsulationNLRI{ + Address: v.String(), + } + case *bgp.EVPNNLRI: + switch r := v.RouteTypeData.(type) { + case *bgp.EVPNEthernetAutoDiscoveryRoute: + nlri = &EVPNEthernetAutoDiscoveryRoute{ + Rd: MarshalRD(r.RD), + Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), + EthernetTag: r.ETag, + Label: r.Label, + } + case *bgp.EVPNMacIPAdvertisementRoute: + nlri = &EVPNMACIPAdvertisementRoute{ + Rd: MarshalRD(r.RD), + Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), + EthernetTag: r.ETag, + MacAddress: r.MacAddress.String(), + IpAddress: r.IPAddress.String(), + Labels: r.Labels, + } + case *bgp.EVPNMulticastEthernetTagRoute: + nlri = &EVPNInclusiveMulticastEthernetTagRoute{ + Rd: MarshalRD(r.RD), + EthernetTag: r.ETag, + IpAddress: r.IPAddress.String(), + } + case *bgp.EVPNEthernetSegmentRoute: + nlri = &EVPNEthernetSegmentRoute{ + Rd: MarshalRD(r.RD), + Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), + IpAddress: r.IPAddress.String(), + } + case *bgp.EVPNIPPrefixRoute: + nlri = &EVPNIPPrefixRoute{ + Rd: MarshalRD(r.RD), + Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), + EthernetTag: r.ETag, + IpPrefix: r.IPPrefix.String(), + IpPrefixLen: uint32(r.IPPrefixLength), + Label: r.Label, + } + } + case *bgp.LabeledVPNIPAddrPrefix: + nlri = &LabeledVPNIPAddressPrefix{ + Labels: v.Labels.Labels, + Rd: MarshalRD(v.RD), + PrefixLen: uint32(v.IPPrefixLen()), + Prefix: v.Prefix.String(), + } + case *bgp.LabeledVPNIPv6AddrPrefix: + nlri = &LabeledVPNIPAddressPrefix{ + Labels: v.Labels.Labels, + Rd: MarshalRD(v.RD), + PrefixLen: uint32(v.IPPrefixLen()), + Prefix: v.Prefix.String(), + } + case *bgp.RouteTargetMembershipNLRI: + nlri = &RouteTargetMembershipNLRI{ + As: v.AS, + Rt: MarshalRT(v.RouteTarget), + } + case *bgp.FlowSpecIPv4Unicast: + nlri = &FlowSpecNLRI{ + Rules: MarshalFlowSpecRules(v.Value), + } + case *bgp.FlowSpecIPv6Unicast: + nlri = &FlowSpecNLRI{ + Rules: MarshalFlowSpecRules(v.Value), + } + case *bgp.FlowSpecIPv4VPN: + nlri = &VPNFlowSpecNLRI{ + Rd: MarshalRD(v.RD()), + Rules: MarshalFlowSpecRules(v.Value), + } + case *bgp.FlowSpecIPv6VPN: + nlri = &VPNFlowSpecNLRI{ + Rd: MarshalRD(v.RD()), + Rules: MarshalFlowSpecRules(v.Value), + } + case *bgp.FlowSpecL2VPN: + nlri = &VPNFlowSpecNLRI{ + Rd: MarshalRD(v.RD()), + Rules: MarshalFlowSpecRules(v.Value), + } + } + + an, _ := ptypes.MarshalAny(nlri) + return an +} + +func MarshalNLRIs(values []bgp.AddrPrefixInterface) []*any.Any { + nlris := make([]*any.Any, 0, len(values)) + for _, value := range values { + nlris = append(nlris, MarshalNLRI(value)) + } + return nlris +} + +func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, error) { + var nlri bgp.AddrPrefixInterface + + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(an, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal nlri: %s", err) + } + + switch v := value.Message.(type) { + case *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: + 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: + switch rf { + case bgp.RF_IPv4_ENCAP: + nlri = bgp.NewEncapNLRI(v.Address) + case bgp.RF_IPv6_ENCAP: + nlri = bgp.NewEncapv6NLRI(v.Address) + } + case *EVPNEthernetAutoDiscoveryRoute: + if rf == bgp.RF_EVPN { + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + esi, err := v.Esi.ToNative() + if err != nil { + return nil, err + } + nlri = bgp.NewEVPNEthernetAutoDiscoveryRoute(rd, *esi, v.EthernetTag, v.Label) + } + case *EVPNMACIPAdvertisementRoute: + if rf == bgp.RF_EVPN { + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + esi, err := v.Esi.ToNative() + if err != nil { + return nil, err + } + nlri = bgp.NewEVPNMacIPAdvertisementRoute(rd, *esi, v.EthernetTag, v.MacAddress, v.IpAddress, v.Labels) + } + case *EVPNInclusiveMulticastEthernetTagRoute: + if rf == bgp.RF_EVPN { + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + nlri = bgp.NewEVPNMulticastEthernetTagRoute(rd, v.EthernetTag, v.IpAddress) + } + case *EVPNEthernetSegmentRoute: + if rf == bgp.RF_EVPN { + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + esi, err := v.Esi.ToNative() + if err != nil { + return nil, err + } + nlri = bgp.NewEVPNEthernetSegmentRoute(rd, *esi, v.IpAddress) + } + case *EVPNIPPrefixRoute: + if rf == bgp.RF_EVPN { + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + esi, err := v.Esi.ToNative() + if err != nil { + return nil, err + } + nlri = bgp.NewEVPNIPPrefixRoute(rd, *esi, v.EthernetTag, uint8(v.IpPrefixLen), v.IpPrefix, v.GwAddress, v.Label) + } + case *LabeledVPNIPAddressPrefix: + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + switch rf { + case bgp.RF_IPv4_VPN: + nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) + case bgp.RF_IPv6_VPN: + nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) + } + case *RouteTargetMembershipNLRI: + rt, err := UnmarshalRT(v.Rt) + if err != nil { + return nil, err + } + nlri = bgp.NewRouteTargetMembershipNLRI(v.As, rt) + case *FlowSpecNLRI: + rules, err := UnmarshalFlowSpecRules(v.Rules) + if err != nil { + return nil, err + } + switch rf { + case bgp.RF_FS_IPv4_UC: + nlri = bgp.NewFlowSpecIPv4Unicast(rules) + case bgp.RF_FS_IPv6_UC: + nlri = bgp.NewFlowSpecIPv6Unicast(rules) + } + case *VPNFlowSpecNLRI: + rd, err := UnmarshalRD(v.Rd) + if err != nil { + return nil, err + } + rules, err := UnmarshalFlowSpecRules(v.Rules) + if err != nil { + return nil, err + } + switch rf { + case bgp.RF_FS_IPv4_VPN: + nlri = bgp.NewFlowSpecIPv4VPN(rd, rules) + case bgp.RF_FS_IPv6_VPN: + nlri = bgp.NewFlowSpecIPv6VPN(rd, rules) + case bgp.RF_FS_L2_VPN: + nlri = bgp.NewFlowSpecL2VPN(rd, rules) + } + } + + if nlri == nil { + return nil, fmt.Errorf("invalid nlri for %s family: %s", rf.String(), value.Message) + } + + return nlri, nil +} + +func UnmarshalNLRIs(rf bgp.RouteFamily, values []*any.Any) ([]bgp.AddrPrefixInterface, error) { + nlris := make([]bgp.AddrPrefixInterface, 0, len(values)) + for _, an := range values { + nlri, err := UnmarshalNLRI(rf, an) + if err != nil { + return nil, err + } + nlris = append(nlris, nlri) + } + return nlris, nil +} + +func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *MpReachNLRIAttribute { + var nexthops []string + if a.SAFI == bgp.SAFI_FLOW_SPEC_UNICAST || a.SAFI == bgp.SAFI_FLOW_SPEC_VPN { + nexthops = nil + } else { + nexthops = []string{a.Nexthop.String()} + if a.LinkLocalNexthop != nil { + nexthops = append(nexthops, a.LinkLocalNexthop.String()) + } + } + return &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{ + 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{ + IsTransitive: true, + SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), + As: uint32(v.AS), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.IPv4AddressSpecificExtended: + r = &IPv4AddressSpecificExtended{ + IsTransitive: true, + SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), + Address: v.IPv4.String(), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.FourOctetAsSpecificExtended: + r = &FourOctetAsSpecificExtended{ + IsTransitive: true, + SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), + As: uint32(v.AS), + LocalAdmin: uint32(v.LocalAdmin), + } + default: + return nil + } + a, _ := ptypes.MarshalAny(r) + return a +} + +func UnmarshalRT(a *any.Any) (bgp.ExtendedCommunityInterface, error) { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(a, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal route target: %s", err) + } + switch v := value.Message.(type) { + case *TwoOctetAsSpecificExtended: + return bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.As), v.LocalAdmin, v.IsTransitive), nil + case *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: + 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) +} + +func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommunities) *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{ + IsTransitive: v.IsTransitive, + SubType: uint32(v.SubType), + As: uint32(v.AS), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.IPv4AddressSpecificExtended: + community = &IPv4AddressSpecificExtended{ + IsTransitive: v.IsTransitive, + SubType: uint32(v.SubType), + Address: v.IPv4.String(), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.FourOctetAsSpecificExtended: + community = &FourOctetAsSpecificExtended{ + IsTransitive: v.IsTransitive, + SubType: uint32(v.SubType), + As: uint32(v.AS), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.ValidationExtended: + community = &ValidationExtended{ + State: uint32(v.State), + } + case *bgp.ColorExtended: + community = &ColorExtended{ + Color: v.Color, + } + case *bgp.EncapExtended: + community = &EncapExtended{ + TunnelType: uint32(v.TunnelType), + } + case *bgp.DefaultGatewayExtended: + community = &DefaultGatewayExtended{} + case *bgp.OpaqueExtended: + community = &OpaqueExtended{ + IsTransitive: v.IsTransitive, + Value: v.Value, + } + case *bgp.ESILabelExtended: + community = &ESILabelExtended{ + IsSingleActive: v.IsSingleActive, + Label: v.Label, + } + case *bgp.ESImportRouteTarget: + community = &ESImportRouteTarget{ + EsImport: v.ESImport.String(), + } + case *bgp.MacMobilityExtended: + community = &MacMobilityExtended{ + IsSticky: v.IsSticky, + SequenceNum: v.Sequence, + } + case *bgp.RouterMacExtended: + community = &RouterMacExtended{ + Mac: v.Mac.String(), + } + case *bgp.TrafficRateExtended: + community = &TrafficRateExtended{ + As: uint32(v.AS), + Rate: v.Rate, + } + case *bgp.TrafficActionExtended: + community = &TrafficActionExtended{ + Terminal: v.Terminal, + Sample: v.Sample, + } + case *bgp.RedirectTwoOctetAsSpecificExtended: + community = &RedirectTwoOctetAsSpecificExtended{ + As: uint32(v.AS), + LocalAdmin: v.LocalAdmin, + } + case *bgp.RedirectIPv4AddressSpecificExtended: + community = &RedirectIPv4AddressSpecificExtended{ + Address: v.IPv4.String(), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.RedirectFourOctetAsSpecificExtended: + community = &RedirectFourOctetAsSpecificExtended{ + As: v.AS, + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.TrafficRemarkExtended: + community = &TrafficRemarkExtended{ + Dscp: uint32(v.DSCP), + } + case *bgp.UnknownExtended: + community = &UnknownExtended{ + Type: uint32(v.Type), + Value: v.Value, + } + default: + log.WithFields(log.Fields{ + "Topic": "protobuf", + "Community": value, + }).Warn("unsupported extended community") + return nil + } + an, _ := ptypes.MarshalAny(community) + communities = append(communities, an) + } + return &ExtendedCommunitiesAttribute{ + Communities: communities, + } +} + +func (a *ExtendedCommunitiesAttribute) ToNative() (*bgp.PathAttributeExtendedCommunities, 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 extended community: %s", err) + } + switch v := value.Message.(type) { + case *TwoOctetAsSpecificExtended: + community = bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.As), v.LocalAdmin, v.IsTransitive) + case *IPv4AddressSpecificExtended: + community = bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) + case *FourOctetAsSpecificExtended: + community = bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive) + case *ValidationExtended: + community = bgp.NewValidationExtended(bgp.ValidationState(v.State)) + case *ColorExtended: + community = bgp.NewColorExtended(v.Color) + case *EncapExtended: + community = bgp.NewEncapExtended(bgp.TunnelType(v.TunnelType)) + case *DefaultGatewayExtended: + community = bgp.NewDefaultGatewayExtended() + case *OpaqueExtended: + community = bgp.NewOpaqueExtended(v.IsTransitive, v.Value) + case *ESILabelExtended: + community = bgp.NewESILabelExtended(v.Label, v.IsSingleActive) + case *ESImportRouteTarget: + community = bgp.NewESImportRouteTarget(v.EsImport) + case *MacMobilityExtended: + community = bgp.NewMacMobilityExtended(v.SequenceNum, v.IsSticky) + case *RouterMacExtended: + community = bgp.NewRoutersMacExtended(v.Mac) + case *TrafficRateExtended: + community = bgp.NewTrafficRateExtended(uint16(v.As), v.Rate) + case *TrafficActionExtended: + community = bgp.NewTrafficActionExtended(v.Terminal, v.Sample) + case *RedirectTwoOctetAsSpecificExtended: + community = bgp.NewRedirectTwoOctetAsSpecificExtended(uint16(v.As), v.LocalAdmin) + case *RedirectIPv4AddressSpecificExtended: + community = bgp.NewRedirectIPv4AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) + case *RedirectFourOctetAsSpecificExtended: + community = bgp.NewRedirectFourOctetAsSpecificExtended(v.As, uint16(v.LocalAdmin)) + case *TrafficRemarkExtended: + community = bgp.NewTrafficRemarkExtended(uint8(v.Dscp)) + case *UnknownExtended: + community = bgp.NewUnknownExtended(bgp.ExtendedCommunityAttrType(v.Type), v.Value) + } + if community == nil { + return nil, fmt.Errorf("invalid extended community: %v", value.Message) + } + communities = append(communities, community) + } + return bgp.NewPathAttributeExtendedCommunities(communities), nil +} + +func NewAs4PathAttributeFromNative(a *bgp.PathAttributeAs4Path) *As4PathAttribute { + segments := make([]*AsSegment, 0, len(a.Value)) + for _, param := range a.Value { + segments = append(segments, &AsSegment{ + Type: uint32(param.Type), + Numbers: param.AS, + }) + } + return &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{ + 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 { + var flags uint32 + if a.IsLeafInfoRequired { + flags |= 0x01 + } + id, _ := a.TunnelID.Serialize() + return &PmsiTunnelAttribute{ + Flags: flags, + Type: uint32(a.TunnelType), + Label: a.Label, + Id: id, + } +} + +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)) + 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{ + Key: sv.Key, + Cookie: sv.Cookie, + } + case *bgp.TunnelEncapSubTLVProtocol: + subTlv = &TunnelEncapSubTLVProtocol{ + Protocol: uint32(sv.Protocol), + } + case *bgp.TunnelEncapSubTLVColor: + subTlv = &TunnelEncapSubTLVColor{ + Color: sv.Color, + } + case *bgp.TunnelEncapSubTLVUnknown: + subTlv = &TunnelEncapSubTLVUnknown{ + Type: uint32(sv.Type), + Value: sv.Value, + } + } + an, _ := ptypes.MarshalAny(subTlv) + subTlvs = append(subTlvs, an) + } + tlvs = append(tlvs, &TunnelEncapTLV{ + Type: uint32(v.Type), + Tlvs: subTlvs, + }) + } + return &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 { + 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{ + IsTransitive: v.IsTransitive, + SubType: uint32(v.SubType), + Address: v.IPv6.String(), + LocalAdmin: uint32(v.LocalAdmin), + } + case *bgp.RedirectIPv6AddressSpecificExtended: + community = &RedirectIPv6AddressSpecificExtended{ + Address: v.IPv6.String(), + LocalAdmin: uint32(v.LocalAdmin), + } + default: + log.WithFields(log.Fields{ + "Topic": "protobuf", + "Attribute": value, + }).Warn("invalid ipv6 extended community") + return nil + } + an, _ := ptypes.MarshalAny(community) + communities = append(communities, an) + } + return &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 { + 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{ + Metric: v.Metric, + } + case *bgp.AigpTLVDefault: + tlv = &AigpTLVUnknown{ + Type: uint32(v.Type()), + Value: v.Value, + } + } + an, _ := ptypes.MarshalAny(tlv) + tlvs = append(tlvs, an) + } + return &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)) + for _, v := range a.Values { + communities = append(communities, &LargeCommunity{ + GlobalAdmin: v.ASN, + LocalData1: v.LocalData1, + LocalData2: v.LocalData2, + }) + } + return &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{ + 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 { + switch a := attr.(type) { + case *bgp.PathAttributeOrigin: + n, _ := ptypes.MarshalAny(NewOriginAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeAsPath: + n, _ := ptypes.MarshalAny(NewAsPathAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeNextHop: + n, _ := ptypes.MarshalAny(NewNextHopAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeMultiExitDisc: + n, _ := ptypes.MarshalAny(NewMultiExitDiscAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeLocalPref: + n, _ := ptypes.MarshalAny(NewLocalPrefAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeAtomicAggregate: + n, _ := ptypes.MarshalAny(NewAtomicAggregateAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeAggregator: + n, _ := ptypes.MarshalAny(NewAggregatorAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeCommunities: + n, _ := ptypes.MarshalAny(NewCommunitiesAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeOriginatorId: + n, _ := ptypes.MarshalAny(NewOriginatorIdAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeClusterList: + n, _ := ptypes.MarshalAny(NewClusterListAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeMpReachNLRI: + n, _ := ptypes.MarshalAny(NewMpReachNLRIAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeMpUnreachNLRI: + n, _ := ptypes.MarshalAny(NewMpUnreachNLRIAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeExtendedCommunities: + n, _ := ptypes.MarshalAny(NewExtendedCommunitiesAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeAs4Path: + n, _ := ptypes.MarshalAny(NewAs4PathAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeAs4Aggregator: + n, _ := ptypes.MarshalAny(NewAs4AggregatorAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributePmsiTunnel: + n, _ := ptypes.MarshalAny(NewPmsiTunnelAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeTunnelEncap: + n, _ := ptypes.MarshalAny(NewTunnelEncapAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeIP6ExtendedCommunities: + n, _ := ptypes.MarshalAny(NewIP6ExtendedCommunitiesAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeAigp: + n, _ := ptypes.MarshalAny(NewAigpAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeLargeCommunities: + n, _ := ptypes.MarshalAny(NewLargeCommunitiesAttributeFromNative(a)) + anyList = append(anyList, n) + case *bgp.PathAttributeUnknown: + n, _ := ptypes.MarshalAny(NewUnknownAttributeFromNative(a)) + anyList = append(anyList, n) + } + } + return anyList +} + +func UnmarshalPathAttributes(values []*any.Any) ([]bgp.PathAttributeInterface, error) { + 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() + } + 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()) + } + typeMap[attr.GetType()] = struct{}{} + attrList = append(attrList, attr) + } + return attrList, nil +} diff --git a/api/attribute.pb.go b/api/attribute.pb.go new file mode 100644 index 00000000..79535b7c --- /dev/null +++ b/api/attribute.pb.go @@ -0,0 +1,2086 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: attribute.proto + +package gobgpapi + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/ptypes/any" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type OriginAttribute struct { + Origin uint32 `protobuf:"varint,1,opt,name=origin" json:"origin,omitempty"` +} + +func (m *OriginAttribute) Reset() { *m = OriginAttribute{} } +func (m *OriginAttribute) String() string { return proto.CompactTextString(m) } +func (*OriginAttribute) ProtoMessage() {} +func (*OriginAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *OriginAttribute) GetOrigin() uint32 { + if m != nil { + return m.Origin + } + return 0 +} + +type AsSegment struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Numbers []uint32 `protobuf:"varint,2,rep,packed,name=numbers" json:"numbers,omitempty"` +} + +func (m *AsSegment) Reset() { *m = AsSegment{} } +func (m *AsSegment) String() string { return proto.CompactTextString(m) } +func (*AsSegment) ProtoMessage() {} +func (*AsSegment) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *AsSegment) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *AsSegment) GetNumbers() []uint32 { + if m != nil { + return m.Numbers + } + return nil +} + +type AsPathAttribute struct { + Segments []*AsSegment `protobuf:"bytes,1,rep,name=segments" json:"segments,omitempty"` +} + +func (m *AsPathAttribute) Reset() { *m = AsPathAttribute{} } +func (m *AsPathAttribute) String() string { return proto.CompactTextString(m) } +func (*AsPathAttribute) ProtoMessage() {} +func (*AsPathAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } + +func (m *AsPathAttribute) GetSegments() []*AsSegment { + if m != nil { + return m.Segments + } + return nil +} + +type NextHopAttribute struct { + NextHop string `protobuf:"bytes,1,opt,name=next_hop,json=nextHop" json:"next_hop,omitempty"` +} + +func (m *NextHopAttribute) Reset() { *m = NextHopAttribute{} } +func (m *NextHopAttribute) String() string { return proto.CompactTextString(m) } +func (*NextHopAttribute) ProtoMessage() {} +func (*NextHopAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } + +func (m *NextHopAttribute) GetNextHop() string { + if m != nil { + return m.NextHop + } + return "" +} + +type MultiExitDiscAttribute struct { + Med uint32 `protobuf:"varint,1,opt,name=med" json:"med,omitempty"` +} + +func (m *MultiExitDiscAttribute) Reset() { *m = MultiExitDiscAttribute{} } +func (m *MultiExitDiscAttribute) String() string { return proto.CompactTextString(m) } +func (*MultiExitDiscAttribute) ProtoMessage() {} +func (*MultiExitDiscAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } + +func (m *MultiExitDiscAttribute) GetMed() uint32 { + if m != nil { + return m.Med + } + return 0 +} + +type LocalPrefAttribute struct { + LocalPref uint32 `protobuf:"varint,1,opt,name=local_pref,json=localPref" json:"local_pref,omitempty"` +} + +func (m *LocalPrefAttribute) Reset() { *m = LocalPrefAttribute{} } +func (m *LocalPrefAttribute) String() string { return proto.CompactTextString(m) } +func (*LocalPrefAttribute) ProtoMessage() {} +func (*LocalPrefAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} } + +func (m *LocalPrefAttribute) GetLocalPref() uint32 { + if m != nil { + return m.LocalPref + } + return 0 +} + +type AtomicAggregateAttribute struct { +} + +func (m *AtomicAggregateAttribute) Reset() { *m = AtomicAggregateAttribute{} } +func (m *AtomicAggregateAttribute) String() string { return proto.CompactTextString(m) } +func (*AtomicAggregateAttribute) ProtoMessage() {} +func (*AtomicAggregateAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} } + +type AggregatorAttribute struct { + As uint32 `protobuf:"varint,2,opt,name=as" json:"as,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"` +} + +func (m *AggregatorAttribute) Reset() { *m = AggregatorAttribute{} } +func (m *AggregatorAttribute) String() string { return proto.CompactTextString(m) } +func (*AggregatorAttribute) ProtoMessage() {} +func (*AggregatorAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} } + +func (m *AggregatorAttribute) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *AggregatorAttribute) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type CommunitiesAttribute struct { + Communities []uint32 `protobuf:"varint,1,rep,packed,name=communities" json:"communities,omitempty"` +} + +func (m *CommunitiesAttribute) Reset() { *m = CommunitiesAttribute{} } +func (m *CommunitiesAttribute) String() string { return proto.CompactTextString(m) } +func (*CommunitiesAttribute) ProtoMessage() {} +func (*CommunitiesAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} } + +func (m *CommunitiesAttribute) GetCommunities() []uint32 { + if m != nil { + return m.Communities + } + return nil +} + +type OriginatorIdAttribute struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` +} + +func (m *OriginatorIdAttribute) Reset() { *m = OriginatorIdAttribute{} } +func (m *OriginatorIdAttribute) String() string { return proto.CompactTextString(m) } +func (*OriginatorIdAttribute) ProtoMessage() {} +func (*OriginatorIdAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} } + +func (m *OriginatorIdAttribute) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +type ClusterListAttribute struct { + Ids []string `protobuf:"bytes,1,rep,name=ids" json:"ids,omitempty"` +} + +func (m *ClusterListAttribute) Reset() { *m = ClusterListAttribute{} } +func (m *ClusterListAttribute) String() string { return proto.CompactTextString(m) } +func (*ClusterListAttribute) ProtoMessage() {} +func (*ClusterListAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{10} } + +func (m *ClusterListAttribute) GetIds() []string { + if m != nil { + return m.Ids + } + return nil +} + +// IPAddressPrefix represents the NLRI for: +// - AFI=1, SAFI=1 +// - AFI=2, SAFI=1 +type IPAddressPrefix struct { + PrefixLen uint32 `protobuf:"varint,1,opt,name=prefix_len,json=prefixLen" json:"prefix_len,omitempty"` + Prefix string `protobuf:"bytes,2,opt,name=prefix" json:"prefix,omitempty"` +} + +func (m *IPAddressPrefix) Reset() { *m = IPAddressPrefix{} } +func (m *IPAddressPrefix) String() string { return proto.CompactTextString(m) } +func (*IPAddressPrefix) ProtoMessage() {} +func (*IPAddressPrefix) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{11} } + +func (m *IPAddressPrefix) GetPrefixLen() uint32 { + if m != nil { + return m.PrefixLen + } + return 0 +} + +func (m *IPAddressPrefix) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +// LabeledIPAddressPrefix represents the NLRI for: +// - AFI=1, SAFI=4 +// - AFI=2, SAFI=4 +type LabeledIPAddressPrefix struct { + Labels []uint32 `protobuf:"varint,1,rep,packed,name=labels" json:"labels,omitempty"` + PrefixLen uint32 `protobuf:"varint,2,opt,name=prefix_len,json=prefixLen" json:"prefix_len,omitempty"` + Prefix string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` +} + +func (m *LabeledIPAddressPrefix) Reset() { *m = LabeledIPAddressPrefix{} } +func (m *LabeledIPAddressPrefix) String() string { return proto.CompactTextString(m) } +func (*LabeledIPAddressPrefix) ProtoMessage() {} +func (*LabeledIPAddressPrefix) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{12} } + +func (m *LabeledIPAddressPrefix) GetLabels() []uint32 { + if m != nil { + return m.Labels + } + return nil +} + +func (m *LabeledIPAddressPrefix) GetPrefixLen() uint32 { + if m != nil { + return m.PrefixLen + } + return 0 +} + +func (m *LabeledIPAddressPrefix) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +// EncapsulationNLRI represents the NLRI for: +// - AFI=1, SAFI=7 +// - AFI=2, SAFI=7 +type EncapsulationNLRI struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` +} + +func (m *EncapsulationNLRI) Reset() { *m = EncapsulationNLRI{} } +func (m *EncapsulationNLRI) String() string { return proto.CompactTextString(m) } +func (*EncapsulationNLRI) ProtoMessage() {} +func (*EncapsulationNLRI) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{13} } + +func (m *EncapsulationNLRI) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type RouteDistinguisherTwoOctetAS struct { + Admin uint32 `protobuf:"varint,1,opt,name=admin" json:"admin,omitempty"` + Assigned uint32 `protobuf:"varint,2,opt,name=assigned" json:"assigned,omitempty"` +} + +func (m *RouteDistinguisherTwoOctetAS) Reset() { *m = RouteDistinguisherTwoOctetAS{} } +func (m *RouteDistinguisherTwoOctetAS) String() string { return proto.CompactTextString(m) } +func (*RouteDistinguisherTwoOctetAS) ProtoMessage() {} +func (*RouteDistinguisherTwoOctetAS) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{14} } + +func (m *RouteDistinguisherTwoOctetAS) GetAdmin() uint32 { + if m != nil { + return m.Admin + } + return 0 +} + +func (m *RouteDistinguisherTwoOctetAS) GetAssigned() uint32 { + if m != nil { + return m.Assigned + } + return 0 +} + +type RouteDistinguisherIPAddress struct { + Admin string `protobuf:"bytes,1,opt,name=admin" json:"admin,omitempty"` + Assigned uint32 `protobuf:"varint,2,opt,name=assigned" json:"assigned,omitempty"` +} + +func (m *RouteDistinguisherIPAddress) Reset() { *m = RouteDistinguisherIPAddress{} } +func (m *RouteDistinguisherIPAddress) String() string { return proto.CompactTextString(m) } +func (*RouteDistinguisherIPAddress) ProtoMessage() {} +func (*RouteDistinguisherIPAddress) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{15} } + +func (m *RouteDistinguisherIPAddress) GetAdmin() string { + if m != nil { + return m.Admin + } + return "" +} + +func (m *RouteDistinguisherIPAddress) GetAssigned() uint32 { + if m != nil { + return m.Assigned + } + return 0 +} + +type RouteDistinguisherFourOctetAS struct { + Admin uint32 `protobuf:"varint,1,opt,name=admin" json:"admin,omitempty"` + Assigned uint32 `protobuf:"varint,2,opt,name=assigned" json:"assigned,omitempty"` +} + +func (m *RouteDistinguisherFourOctetAS) Reset() { *m = RouteDistinguisherFourOctetAS{} } +func (m *RouteDistinguisherFourOctetAS) String() string { return proto.CompactTextString(m) } +func (*RouteDistinguisherFourOctetAS) ProtoMessage() {} +func (*RouteDistinguisherFourOctetAS) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{16} } + +func (m *RouteDistinguisherFourOctetAS) GetAdmin() uint32 { + if m != nil { + return m.Admin + } + return 0 +} + +func (m *RouteDistinguisherFourOctetAS) GetAssigned() uint32 { + if m != nil { + return m.Assigned + } + return 0 +} + +type EthernetSegmentIdentifier struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *EthernetSegmentIdentifier) Reset() { *m = EthernetSegmentIdentifier{} } +func (m *EthernetSegmentIdentifier) String() string { return proto.CompactTextString(m) } +func (*EthernetSegmentIdentifier) ProtoMessage() {} +func (*EthernetSegmentIdentifier) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{17} } + +func (m *EthernetSegmentIdentifier) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *EthernetSegmentIdentifier) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +// EVPNEthernetAutoDiscoveryRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=1 +type EVPNEthernetAutoDiscoveryRoute struct { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + Rd *google_protobuf.Any `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` + Esi *EthernetSegmentIdentifier `protobuf:"bytes,2,opt,name=esi" json:"esi,omitempty"` + EthernetTag uint32 `protobuf:"varint,3,opt,name=ethernet_tag,json=ethernetTag" json:"ethernet_tag,omitempty"` + Label uint32 `protobuf:"varint,4,opt,name=label" json:"label,omitempty"` +} + +func (m *EVPNEthernetAutoDiscoveryRoute) Reset() { *m = EVPNEthernetAutoDiscoveryRoute{} } +func (m *EVPNEthernetAutoDiscoveryRoute) String() string { return proto.CompactTextString(m) } +func (*EVPNEthernetAutoDiscoveryRoute) ProtoMessage() {} +func (*EVPNEthernetAutoDiscoveryRoute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{18} } + +func (m *EVPNEthernetAutoDiscoveryRoute) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *EVPNEthernetAutoDiscoveryRoute) GetEsi() *EthernetSegmentIdentifier { + if m != nil { + return m.Esi + } + return nil +} + +func (m *EVPNEthernetAutoDiscoveryRoute) GetEthernetTag() uint32 { + if m != nil { + return m.EthernetTag + } + return 0 +} + +func (m *EVPNEthernetAutoDiscoveryRoute) GetLabel() uint32 { + if m != nil { + return m.Label + } + return 0 +} + +// EVPNMACIPAdvertisementRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=2 +type EVPNMACIPAdvertisementRoute struct { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + Rd *google_protobuf.Any `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` + Esi *EthernetSegmentIdentifier `protobuf:"bytes,2,opt,name=esi" json:"esi,omitempty"` + EthernetTag uint32 `protobuf:"varint,3,opt,name=ethernet_tag,json=ethernetTag" json:"ethernet_tag,omitempty"` + MacAddress string `protobuf:"bytes,4,opt,name=mac_address,json=macAddress" json:"mac_address,omitempty"` + IpAddress string `protobuf:"bytes,5,opt,name=ip_address,json=ipAddress" json:"ip_address,omitempty"` + Labels []uint32 `protobuf:"varint,6,rep,packed,name=labels" json:"labels,omitempty"` +} + +func (m *EVPNMACIPAdvertisementRoute) Reset() { *m = EVPNMACIPAdvertisementRoute{} } +func (m *EVPNMACIPAdvertisementRoute) String() string { return proto.CompactTextString(m) } +func (*EVPNMACIPAdvertisementRoute) ProtoMessage() {} +func (*EVPNMACIPAdvertisementRoute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{19} } + +func (m *EVPNMACIPAdvertisementRoute) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *EVPNMACIPAdvertisementRoute) GetEsi() *EthernetSegmentIdentifier { + if m != nil { + return m.Esi + } + return nil +} + +func (m *EVPNMACIPAdvertisementRoute) GetEthernetTag() uint32 { + if m != nil { + return m.EthernetTag + } + return 0 +} + +func (m *EVPNMACIPAdvertisementRoute) GetMacAddress() string { + if m != nil { + return m.MacAddress + } + return "" +} + +func (m *EVPNMACIPAdvertisementRoute) GetIpAddress() string { + if m != nil { + return m.IpAddress + } + return "" +} + +func (m *EVPNMACIPAdvertisementRoute) GetLabels() []uint32 { + if m != nil { + return m.Labels + } + return nil +} + +// EVPNInclusiveMulticastEthernetTagRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=3 +type EVPNInclusiveMulticastEthernetTagRoute struct { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + Rd *google_protobuf.Any `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` + EthernetTag uint32 `protobuf:"varint,2,opt,name=ethernet_tag,json=ethernetTag" json:"ethernet_tag,omitempty"` + IpAddress string `protobuf:"bytes,3,opt,name=ip_address,json=ipAddress" json:"ip_address,omitempty"` +} + +func (m *EVPNInclusiveMulticastEthernetTagRoute) Reset() { + *m = EVPNInclusiveMulticastEthernetTagRoute{} +} +func (m *EVPNInclusiveMulticastEthernetTagRoute) String() string { return proto.CompactTextString(m) } +func (*EVPNInclusiveMulticastEthernetTagRoute) ProtoMessage() {} +func (*EVPNInclusiveMulticastEthernetTagRoute) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{20} +} + +func (m *EVPNInclusiveMulticastEthernetTagRoute) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *EVPNInclusiveMulticastEthernetTagRoute) GetEthernetTag() uint32 { + if m != nil { + return m.EthernetTag + } + return 0 +} + +func (m *EVPNInclusiveMulticastEthernetTagRoute) GetIpAddress() string { + if m != nil { + return m.IpAddress + } + return "" +} + +// EVPNEthernetSegmentRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=4 +type EVPNEthernetSegmentRoute struct { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + Rd *google_protobuf.Any `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` + Esi *EthernetSegmentIdentifier `protobuf:"bytes,2,opt,name=esi" json:"esi,omitempty"` + IpAddress string `protobuf:"bytes,3,opt,name=ip_address,json=ipAddress" json:"ip_address,omitempty"` +} + +func (m *EVPNEthernetSegmentRoute) Reset() { *m = EVPNEthernetSegmentRoute{} } +func (m *EVPNEthernetSegmentRoute) String() string { return proto.CompactTextString(m) } +func (*EVPNEthernetSegmentRoute) ProtoMessage() {} +func (*EVPNEthernetSegmentRoute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{21} } + +func (m *EVPNEthernetSegmentRoute) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *EVPNEthernetSegmentRoute) GetEsi() *EthernetSegmentIdentifier { + if m != nil { + return m.Esi + } + return nil +} + +func (m *EVPNEthernetSegmentRoute) GetIpAddress() string { + if m != nil { + return m.IpAddress + } + return "" +} + +// EVPNIPPrefixRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=5 +type EVPNIPPrefixRoute struct { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + Rd *google_protobuf.Any `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` + Esi *EthernetSegmentIdentifier `protobuf:"bytes,2,opt,name=esi" json:"esi,omitempty"` + EthernetTag uint32 `protobuf:"varint,3,opt,name=ethernet_tag,json=ethernetTag" json:"ethernet_tag,omitempty"` + IpPrefix string `protobuf:"bytes,4,opt,name=ip_prefix,json=ipPrefix" json:"ip_prefix,omitempty"` + IpPrefixLen uint32 `protobuf:"varint,5,opt,name=ip_prefix_len,json=ipPrefixLen" json:"ip_prefix_len,omitempty"` + GwAddress string `protobuf:"bytes,6,opt,name=gw_address,json=gwAddress" json:"gw_address,omitempty"` + Label uint32 `protobuf:"varint,7,opt,name=label" json:"label,omitempty"` +} + +func (m *EVPNIPPrefixRoute) Reset() { *m = EVPNIPPrefixRoute{} } +func (m *EVPNIPPrefixRoute) String() string { return proto.CompactTextString(m) } +func (*EVPNIPPrefixRoute) ProtoMessage() {} +func (*EVPNIPPrefixRoute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{22} } + +func (m *EVPNIPPrefixRoute) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *EVPNIPPrefixRoute) GetEsi() *EthernetSegmentIdentifier { + if m != nil { + return m.Esi + } + return nil +} + +func (m *EVPNIPPrefixRoute) GetEthernetTag() uint32 { + if m != nil { + return m.EthernetTag + } + return 0 +} + +func (m *EVPNIPPrefixRoute) GetIpPrefix() string { + if m != nil { + return m.IpPrefix + } + return "" +} + +func (m *EVPNIPPrefixRoute) GetIpPrefixLen() uint32 { + if m != nil { + return m.IpPrefixLen + } + return 0 +} + +func (m *EVPNIPPrefixRoute) GetGwAddress() string { + if m != nil { + return m.GwAddress + } + return "" +} + +func (m *EVPNIPPrefixRoute) GetLabel() uint32 { + if m != nil { + return m.Label + } + return 0 +} + +// LabeledVPNIPAddressPrefix represents the NLRI for: +// - AFI=1, SAFI=128 +// - AFI=2, SAFI=128 +type LabeledVPNIPAddressPrefix struct { + Labels []uint32 `protobuf:"varint,1,rep,packed,name=labels" json:"labels,omitempty"` + // One of: + // - TwoOctetAsSpecificExtended + // - IPv4AddressSpecificExtended + // - FourOctetAsSpecificExtended + Rd *google_protobuf.Any `protobuf:"bytes,2,opt,name=rd" json:"rd,omitempty"` + PrefixLen uint32 `protobuf:"varint,3,opt,name=prefix_len,json=prefixLen" json:"prefix_len,omitempty"` + Prefix string `protobuf:"bytes,4,opt,name=prefix" json:"prefix,omitempty"` +} + +func (m *LabeledVPNIPAddressPrefix) Reset() { *m = LabeledVPNIPAddressPrefix{} } +func (m *LabeledVPNIPAddressPrefix) String() string { return proto.CompactTextString(m) } +func (*LabeledVPNIPAddressPrefix) ProtoMessage() {} +func (*LabeledVPNIPAddressPrefix) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{23} } + +func (m *LabeledVPNIPAddressPrefix) GetLabels() []uint32 { + if m != nil { + return m.Labels + } + return nil +} + +func (m *LabeledVPNIPAddressPrefix) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *LabeledVPNIPAddressPrefix) GetPrefixLen() uint32 { + if m != nil { + return m.PrefixLen + } + return 0 +} + +func (m *LabeledVPNIPAddressPrefix) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +// RouteTargetMembershipNLRI represents the NLRI for: +// - AFI=1, SAFI=132 +type RouteTargetMembershipNLRI struct { + As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"` + // One of: + // - TwoOctetAsSpecificExtended + // - IPv4AddressSpecificExtended + // - FourOctetAsSpecificExtended + Rt *google_protobuf.Any `protobuf:"bytes,2,opt,name=rt" json:"rt,omitempty"` +} + +func (m *RouteTargetMembershipNLRI) Reset() { *m = RouteTargetMembershipNLRI{} } +func (m *RouteTargetMembershipNLRI) String() string { return proto.CompactTextString(m) } +func (*RouteTargetMembershipNLRI) ProtoMessage() {} +func (*RouteTargetMembershipNLRI) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{24} } + +func (m *RouteTargetMembershipNLRI) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *RouteTargetMembershipNLRI) GetRt() *google_protobuf.Any { + if m != nil { + return m.Rt + } + return nil +} + +type FlowSpecIPPrefix struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + PrefixLen uint32 `protobuf:"varint,2,opt,name=prefix_len,json=prefixLen" json:"prefix_len,omitempty"` + Prefix string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` + // IPv6 only + Offset uint32 `protobuf:"varint,4,opt,name=offset" json:"offset,omitempty"` +} + +func (m *FlowSpecIPPrefix) Reset() { *m = FlowSpecIPPrefix{} } +func (m *FlowSpecIPPrefix) String() string { return proto.CompactTextString(m) } +func (*FlowSpecIPPrefix) ProtoMessage() {} +func (*FlowSpecIPPrefix) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{25} } + +func (m *FlowSpecIPPrefix) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *FlowSpecIPPrefix) GetPrefixLen() uint32 { + if m != nil { + return m.PrefixLen + } + return 0 +} + +func (m *FlowSpecIPPrefix) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +func (m *FlowSpecIPPrefix) GetOffset() uint32 { + if m != nil { + return m.Offset + } + return 0 +} + +type FlowSpecMAC struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` +} + +func (m *FlowSpecMAC) Reset() { *m = FlowSpecMAC{} } +func (m *FlowSpecMAC) String() string { return proto.CompactTextString(m) } +func (*FlowSpecMAC) ProtoMessage() {} +func (*FlowSpecMAC) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{26} } + +func (m *FlowSpecMAC) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *FlowSpecMAC) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type FlowSpecComponentItem struct { + // Operator for Numeric type, Operand for Bitmask type + Op uint32 `protobuf:"varint,1,opt,name=op" json:"op,omitempty"` + Value uint64 `protobuf:"varint,2,opt,name=value" json:"value,omitempty"` +} + +func (m *FlowSpecComponentItem) Reset() { *m = FlowSpecComponentItem{} } +func (m *FlowSpecComponentItem) String() string { return proto.CompactTextString(m) } +func (*FlowSpecComponentItem) ProtoMessage() {} +func (*FlowSpecComponentItem) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{27} } + +func (m *FlowSpecComponentItem) GetOp() uint32 { + if m != nil { + return m.Op + } + return 0 +} + +func (m *FlowSpecComponentItem) GetValue() uint64 { + if m != nil { + return m.Value + } + return 0 +} + +type FlowSpecComponent struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Items []*FlowSpecComponentItem `protobuf:"bytes,2,rep,name=items" json:"items,omitempty"` +} + +func (m *FlowSpecComponent) Reset() { *m = FlowSpecComponent{} } +func (m *FlowSpecComponent) String() string { return proto.CompactTextString(m) } +func (*FlowSpecComponent) ProtoMessage() {} +func (*FlowSpecComponent) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{28} } + +func (m *FlowSpecComponent) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *FlowSpecComponent) GetItems() []*FlowSpecComponentItem { + if m != nil { + return m.Items + } + return nil +} + +// FlowSpecNLRI represents the NLRI for: +// - AFI=1, SAFI=133 +// - AFI=2, SAFI=133 +type FlowSpecNLRI struct { + // One of: + // - FlowSpecIPPrefix + // - FlowSpecMAC + // - FlowSpecComponent + Rules []*google_protobuf.Any `protobuf:"bytes,1,rep,name=rules" json:"rules,omitempty"` +} + +func (m *FlowSpecNLRI) Reset() { *m = FlowSpecNLRI{} } +func (m *FlowSpecNLRI) String() string { return proto.CompactTextString(m) } +func (*FlowSpecNLRI) ProtoMessage() {} +func (*FlowSpecNLRI) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{29} } + +func (m *FlowSpecNLRI) GetRules() []*google_protobuf.Any { + if m != nil { + return m.Rules + } + return nil +} + +// VPNFlowSpecNLRI represents the NLRI for: +// - AFI=1, SAFI=134 +// - AFI=2, SAFI=134 +// - AFI=25, SAFI=134 +type VPNFlowSpecNLRI struct { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + Rd *google_protobuf.Any `protobuf:"bytes,1,opt,name=rd" json:"rd,omitempty"` + // One of: + // - FlowSpecIPPrefix + // - FlowSpecMAC + // - FlowSpecComponent + Rules []*google_protobuf.Any `protobuf:"bytes,2,rep,name=rules" json:"rules,omitempty"` +} + +func (m *VPNFlowSpecNLRI) Reset() { *m = VPNFlowSpecNLRI{} } +func (m *VPNFlowSpecNLRI) String() string { return proto.CompactTextString(m) } +func (*VPNFlowSpecNLRI) ProtoMessage() {} +func (*VPNFlowSpecNLRI) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{30} } + +func (m *VPNFlowSpecNLRI) GetRd() *google_protobuf.Any { + if m != nil { + return m.Rd + } + return nil +} + +func (m *VPNFlowSpecNLRI) GetRules() []*google_protobuf.Any { + if m != nil { + return m.Rules + } + return nil +} + +// OpaqueNLRI represents the NLRI for: +// - AFI=16397, SAFI=241 +type OpaqueNLRI struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *OpaqueNLRI) Reset() { *m = OpaqueNLRI{} } +func (m *OpaqueNLRI) String() string { return proto.CompactTextString(m) } +func (*OpaqueNLRI) ProtoMessage() {} +func (*OpaqueNLRI) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{31} } + +func (m *OpaqueNLRI) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *OpaqueNLRI) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type MpReachNLRIAttribute struct { + Family uint32 `protobuf:"varint,1,opt,name=family" json:"family,omitempty"` + NextHops []string `protobuf:"bytes,2,rep,name=next_hops,json=nextHops" json:"next_hops,omitempty"` + // Each NLRI must be one of: + // - IPAddressPrefix + // - LabeledIPAddressPrefix + // - EncapsulationNLRI + // - EVPNEthernetAutoDiscoveryRoute + // - EVPNMACIPAdvertisementRoute + // - EVPNInclusiveMulticastEthernetTagRoute + // - EVPNEthernetSegmentRoute + // - EVPNIPPrefixRoute + // - LabeledVPNIPAddressPrefix + // - RouteTargetMembershipNLRI + // - FlowSpecNLRI + // - VPNFlowSpecNLRI + // - OpaqueNLRI + Nlris []*google_protobuf.Any `protobuf:"bytes,3,rep,name=nlris" json:"nlris,omitempty"` +} + +func (m *MpReachNLRIAttribute) Reset() { *m = MpReachNLRIAttribute{} } +func (m *MpReachNLRIAttribute) String() string { return proto.CompactTextString(m) } +func (*MpReachNLRIAttribute) ProtoMessage() {} +func (*MpReachNLRIAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{32} } + +func (m *MpReachNLRIAttribute) GetFamily() uint32 { + if m != nil { + return m.Family + } + return 0 +} + +func (m *MpReachNLRIAttribute) GetNextHops() []string { + if m != nil { + return m.NextHops + } + return nil +} + +func (m *MpReachNLRIAttribute) GetNlris() []*google_protobuf.Any { + if m != nil { + return m.Nlris + } + return nil +} + +type MpUnreachNLRIAttribute struct { + Family uint32 `protobuf:"varint,1,opt,name=family" json:"family,omitempty"` + // The same as NLRI field of MpReachNLRIAttribute + Nlris []*google_protobuf.Any `protobuf:"bytes,3,rep,name=nlris" json:"nlris,omitempty"` +} + +func (m *MpUnreachNLRIAttribute) Reset() { *m = MpUnreachNLRIAttribute{} } +func (m *MpUnreachNLRIAttribute) String() string { return proto.CompactTextString(m) } +func (*MpUnreachNLRIAttribute) ProtoMessage() {} +func (*MpUnreachNLRIAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{33} } + +func (m *MpUnreachNLRIAttribute) GetFamily() uint32 { + if m != nil { + return m.Family + } + return 0 +} + +func (m *MpUnreachNLRIAttribute) GetNlris() []*google_protobuf.Any { + if m != nil { + return m.Nlris + } + return nil +} + +type TwoOctetAsSpecificExtended struct { + IsTransitive bool `protobuf:"varint,1,opt,name=is_transitive,json=isTransitive" json:"is_transitive,omitempty"` + SubType uint32 `protobuf:"varint,2,opt,name=sub_type,json=subType" json:"sub_type,omitempty"` + As uint32 `protobuf:"varint,3,opt,name=as" json:"as,omitempty"` + LocalAdmin uint32 `protobuf:"varint,4,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *TwoOctetAsSpecificExtended) Reset() { *m = TwoOctetAsSpecificExtended{} } +func (m *TwoOctetAsSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*TwoOctetAsSpecificExtended) ProtoMessage() {} +func (*TwoOctetAsSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{34} } + +func (m *TwoOctetAsSpecificExtended) GetIsTransitive() bool { + if m != nil { + return m.IsTransitive + } + return false +} + +func (m *TwoOctetAsSpecificExtended) GetSubType() uint32 { + if m != nil { + return m.SubType + } + return 0 +} + +func (m *TwoOctetAsSpecificExtended) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *TwoOctetAsSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type IPv4AddressSpecificExtended struct { + IsTransitive bool `protobuf:"varint,1,opt,name=is_transitive,json=isTransitive" json:"is_transitive,omitempty"` + SubType uint32 `protobuf:"varint,2,opt,name=sub_type,json=subType" json:"sub_type,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"` + LocalAdmin uint32 `protobuf:"varint,4,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *IPv4AddressSpecificExtended) Reset() { *m = IPv4AddressSpecificExtended{} } +func (m *IPv4AddressSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*IPv4AddressSpecificExtended) ProtoMessage() {} +func (*IPv4AddressSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{35} } + +func (m *IPv4AddressSpecificExtended) GetIsTransitive() bool { + if m != nil { + return m.IsTransitive + } + return false +} + +func (m *IPv4AddressSpecificExtended) GetSubType() uint32 { + if m != nil { + return m.SubType + } + return 0 +} + +func (m *IPv4AddressSpecificExtended) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *IPv4AddressSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type FourOctetAsSpecificExtended struct { + IsTransitive bool `protobuf:"varint,1,opt,name=is_transitive,json=isTransitive" json:"is_transitive,omitempty"` + SubType uint32 `protobuf:"varint,2,opt,name=sub_type,json=subType" json:"sub_type,omitempty"` + As uint32 `protobuf:"varint,3,opt,name=as" json:"as,omitempty"` + LocalAdmin uint32 `protobuf:"varint,4,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *FourOctetAsSpecificExtended) Reset() { *m = FourOctetAsSpecificExtended{} } +func (m *FourOctetAsSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*FourOctetAsSpecificExtended) ProtoMessage() {} +func (*FourOctetAsSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{36} } + +func (m *FourOctetAsSpecificExtended) GetIsTransitive() bool { + if m != nil { + return m.IsTransitive + } + return false +} + +func (m *FourOctetAsSpecificExtended) GetSubType() uint32 { + if m != nil { + return m.SubType + } + return 0 +} + +func (m *FourOctetAsSpecificExtended) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *FourOctetAsSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type ValidationExtended struct { + State uint32 `protobuf:"varint,1,opt,name=state" json:"state,omitempty"` +} + +func (m *ValidationExtended) Reset() { *m = ValidationExtended{} } +func (m *ValidationExtended) String() string { return proto.CompactTextString(m) } +func (*ValidationExtended) ProtoMessage() {} +func (*ValidationExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{37} } + +func (m *ValidationExtended) GetState() uint32 { + if m != nil { + return m.State + } + return 0 +} + +type ColorExtended struct { + Color uint32 `protobuf:"varint,1,opt,name=color" json:"color,omitempty"` +} + +func (m *ColorExtended) Reset() { *m = ColorExtended{} } +func (m *ColorExtended) String() string { return proto.CompactTextString(m) } +func (*ColorExtended) ProtoMessage() {} +func (*ColorExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{38} } + +func (m *ColorExtended) GetColor() uint32 { + if m != nil { + return m.Color + } + return 0 +} + +type EncapExtended struct { + TunnelType uint32 `protobuf:"varint,1,opt,name=tunnel_type,json=tunnelType" json:"tunnel_type,omitempty"` +} + +func (m *EncapExtended) Reset() { *m = EncapExtended{} } +func (m *EncapExtended) String() string { return proto.CompactTextString(m) } +func (*EncapExtended) ProtoMessage() {} +func (*EncapExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{39} } + +func (m *EncapExtended) GetTunnelType() uint32 { + if m != nil { + return m.TunnelType + } + return 0 +} + +type DefaultGatewayExtended struct { +} + +func (m *DefaultGatewayExtended) Reset() { *m = DefaultGatewayExtended{} } +func (m *DefaultGatewayExtended) String() string { return proto.CompactTextString(m) } +func (*DefaultGatewayExtended) ProtoMessage() {} +func (*DefaultGatewayExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{40} } + +type OpaqueExtended struct { + IsTransitive bool `protobuf:"varint,1,opt,name=is_transitive,json=isTransitive" json:"is_transitive,omitempty"` + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *OpaqueExtended) Reset() { *m = OpaqueExtended{} } +func (m *OpaqueExtended) String() string { return proto.CompactTextString(m) } +func (*OpaqueExtended) ProtoMessage() {} +func (*OpaqueExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{41} } + +func (m *OpaqueExtended) GetIsTransitive() bool { + if m != nil { + return m.IsTransitive + } + return false +} + +func (m *OpaqueExtended) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type ESILabelExtended struct { + IsSingleActive bool `protobuf:"varint,1,opt,name=is_single_active,json=isSingleActive" json:"is_single_active,omitempty"` + Label uint32 `protobuf:"varint,2,opt,name=label" json:"label,omitempty"` +} + +func (m *ESILabelExtended) Reset() { *m = ESILabelExtended{} } +func (m *ESILabelExtended) String() string { return proto.CompactTextString(m) } +func (*ESILabelExtended) ProtoMessage() {} +func (*ESILabelExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{42} } + +func (m *ESILabelExtended) GetIsSingleActive() bool { + if m != nil { + return m.IsSingleActive + } + return false +} + +func (m *ESILabelExtended) GetLabel() uint32 { + if m != nil { + return m.Label + } + return 0 +} + +type ESImportRouteTarget struct { + EsImport string `protobuf:"bytes,1,opt,name=es_import,json=esImport" json:"es_import,omitempty"` +} + +func (m *ESImportRouteTarget) Reset() { *m = ESImportRouteTarget{} } +func (m *ESImportRouteTarget) String() string { return proto.CompactTextString(m) } +func (*ESImportRouteTarget) ProtoMessage() {} +func (*ESImportRouteTarget) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{43} } + +func (m *ESImportRouteTarget) GetEsImport() string { + if m != nil { + return m.EsImport + } + return "" +} + +type MacMobilityExtended struct { + IsSticky bool `protobuf:"varint,1,opt,name=is_sticky,json=isSticky" json:"is_sticky,omitempty"` + SequenceNum uint32 `protobuf:"varint,2,opt,name=sequence_num,json=sequenceNum" json:"sequence_num,omitempty"` +} + +func (m *MacMobilityExtended) Reset() { *m = MacMobilityExtended{} } +func (m *MacMobilityExtended) String() string { return proto.CompactTextString(m) } +func (*MacMobilityExtended) ProtoMessage() {} +func (*MacMobilityExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{44} } + +func (m *MacMobilityExtended) GetIsSticky() bool { + if m != nil { + return m.IsSticky + } + return false +} + +func (m *MacMobilityExtended) GetSequenceNum() uint32 { + if m != nil { + return m.SequenceNum + } + return 0 +} + +type RouterMacExtended struct { + Mac string `protobuf:"bytes,1,opt,name=mac" json:"mac,omitempty"` +} + +func (m *RouterMacExtended) Reset() { *m = RouterMacExtended{} } +func (m *RouterMacExtended) String() string { return proto.CompactTextString(m) } +func (*RouterMacExtended) ProtoMessage() {} +func (*RouterMacExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{45} } + +func (m *RouterMacExtended) GetMac() string { + if m != nil { + return m.Mac + } + return "" +} + +type TrafficRateExtended struct { + As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"` + Rate float32 `protobuf:"fixed32,2,opt,name=rate" json:"rate,omitempty"` +} + +func (m *TrafficRateExtended) Reset() { *m = TrafficRateExtended{} } +func (m *TrafficRateExtended) String() string { return proto.CompactTextString(m) } +func (*TrafficRateExtended) ProtoMessage() {} +func (*TrafficRateExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{46} } + +func (m *TrafficRateExtended) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *TrafficRateExtended) GetRate() float32 { + if m != nil { + return m.Rate + } + return 0 +} + +type TrafficActionExtended struct { + Terminal bool `protobuf:"varint,1,opt,name=terminal" json:"terminal,omitempty"` + Sample bool `protobuf:"varint,2,opt,name=sample" json:"sample,omitempty"` +} + +func (m *TrafficActionExtended) Reset() { *m = TrafficActionExtended{} } +func (m *TrafficActionExtended) String() string { return proto.CompactTextString(m) } +func (*TrafficActionExtended) ProtoMessage() {} +func (*TrafficActionExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{47} } + +func (m *TrafficActionExtended) GetTerminal() bool { + if m != nil { + return m.Terminal + } + return false +} + +func (m *TrafficActionExtended) GetSample() bool { + if m != nil { + return m.Sample + } + return false +} + +type RedirectTwoOctetAsSpecificExtended struct { + As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"` + LocalAdmin uint32 `protobuf:"varint,2,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *RedirectTwoOctetAsSpecificExtended) Reset() { *m = RedirectTwoOctetAsSpecificExtended{} } +func (m *RedirectTwoOctetAsSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*RedirectTwoOctetAsSpecificExtended) ProtoMessage() {} +func (*RedirectTwoOctetAsSpecificExtended) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{48} +} + +func (m *RedirectTwoOctetAsSpecificExtended) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *RedirectTwoOctetAsSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type RedirectIPv4AddressSpecificExtended struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + LocalAdmin uint32 `protobuf:"varint,2,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *RedirectIPv4AddressSpecificExtended) Reset() { *m = RedirectIPv4AddressSpecificExtended{} } +func (m *RedirectIPv4AddressSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*RedirectIPv4AddressSpecificExtended) ProtoMessage() {} +func (*RedirectIPv4AddressSpecificExtended) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{49} +} + +func (m *RedirectIPv4AddressSpecificExtended) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *RedirectIPv4AddressSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type RedirectFourOctetAsSpecificExtended struct { + As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"` + LocalAdmin uint32 `protobuf:"varint,2,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *RedirectFourOctetAsSpecificExtended) Reset() { *m = RedirectFourOctetAsSpecificExtended{} } +func (m *RedirectFourOctetAsSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*RedirectFourOctetAsSpecificExtended) ProtoMessage() {} +func (*RedirectFourOctetAsSpecificExtended) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{50} +} + +func (m *RedirectFourOctetAsSpecificExtended) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *RedirectFourOctetAsSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type TrafficRemarkExtended struct { + Dscp uint32 `protobuf:"varint,1,opt,name=dscp" json:"dscp,omitempty"` +} + +func (m *TrafficRemarkExtended) Reset() { *m = TrafficRemarkExtended{} } +func (m *TrafficRemarkExtended) String() string { return proto.CompactTextString(m) } +func (*TrafficRemarkExtended) ProtoMessage() {} +func (*TrafficRemarkExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{51} } + +func (m *TrafficRemarkExtended) GetDscp() uint32 { + if m != nil { + return m.Dscp + } + return 0 +} + +type UnknownExtended struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *UnknownExtended) Reset() { *m = UnknownExtended{} } +func (m *UnknownExtended) String() string { return proto.CompactTextString(m) } +func (*UnknownExtended) ProtoMessage() {} +func (*UnknownExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{52} } + +func (m *UnknownExtended) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *UnknownExtended) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type ExtendedCommunitiesAttribute struct { + // Each Community must be one of: + // - TwoOctetAsSpecificExtended + // - IPv4AddressSpecificExtended + // - FourOctetAsSpecificExtended + // - OpaqueExtended + // - ESILabelExtended + // - MacMobilityExtended + // - RouterMacExtended + // - TrafficRateExtended + // - TrafficActionExtended + // - RedirectTwoOctetAsSpecificExtended + // - RedirectIPv4AddressSpecificExtended + // - RedirectFourOctetAsSpecificExtended + // - TrafficRemarkExtended + // - UnknownExtended + Communities []*google_protobuf.Any `protobuf:"bytes,1,rep,name=communities" json:"communities,omitempty"` +} + +func (m *ExtendedCommunitiesAttribute) Reset() { *m = ExtendedCommunitiesAttribute{} } +func (m *ExtendedCommunitiesAttribute) String() string { return proto.CompactTextString(m) } +func (*ExtendedCommunitiesAttribute) ProtoMessage() {} +func (*ExtendedCommunitiesAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{53} } + +func (m *ExtendedCommunitiesAttribute) GetCommunities() []*google_protobuf.Any { + if m != nil { + return m.Communities + } + return nil +} + +type As4PathAttribute struct { + Segments []*AsSegment `protobuf:"bytes,1,rep,name=segments" json:"segments,omitempty"` +} + +func (m *As4PathAttribute) Reset() { *m = As4PathAttribute{} } +func (m *As4PathAttribute) String() string { return proto.CompactTextString(m) } +func (*As4PathAttribute) ProtoMessage() {} +func (*As4PathAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{54} } + +func (m *As4PathAttribute) GetSegments() []*AsSegment { + if m != nil { + return m.Segments + } + return nil +} + +type As4AggregatorAttribute struct { + As uint32 `protobuf:"varint,2,opt,name=as" json:"as,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"` +} + +func (m *As4AggregatorAttribute) Reset() { *m = As4AggregatorAttribute{} } +func (m *As4AggregatorAttribute) String() string { return proto.CompactTextString(m) } +func (*As4AggregatorAttribute) ProtoMessage() {} +func (*As4AggregatorAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{55} } + +func (m *As4AggregatorAttribute) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +func (m *As4AggregatorAttribute) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type PmsiTunnelAttribute struct { + Flags uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` + Type uint32 `protobuf:"varint,2,opt,name=type" json:"type,omitempty"` + Label uint32 `protobuf:"varint,3,opt,name=label" json:"label,omitempty"` + Id []byte `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *PmsiTunnelAttribute) Reset() { *m = PmsiTunnelAttribute{} } +func (m *PmsiTunnelAttribute) String() string { return proto.CompactTextString(m) } +func (*PmsiTunnelAttribute) ProtoMessage() {} +func (*PmsiTunnelAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{56} } + +func (m *PmsiTunnelAttribute) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +func (m *PmsiTunnelAttribute) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *PmsiTunnelAttribute) GetLabel() uint32 { + if m != nil { + return m.Label + } + return 0 +} + +func (m *PmsiTunnelAttribute) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type TunnelEncapSubTLVEncapsulation struct { + Key uint32 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + Cookie []byte `protobuf:"bytes,2,opt,name=cookie,proto3" json:"cookie,omitempty"` +} + +func (m *TunnelEncapSubTLVEncapsulation) Reset() { *m = TunnelEncapSubTLVEncapsulation{} } +func (m *TunnelEncapSubTLVEncapsulation) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapSubTLVEncapsulation) ProtoMessage() {} +func (*TunnelEncapSubTLVEncapsulation) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{57} } + +func (m *TunnelEncapSubTLVEncapsulation) GetKey() uint32 { + if m != nil { + return m.Key + } + return 0 +} + +func (m *TunnelEncapSubTLVEncapsulation) GetCookie() []byte { + if m != nil { + return m.Cookie + } + return nil +} + +type TunnelEncapSubTLVProtocol struct { + Protocol uint32 `protobuf:"varint,1,opt,name=protocol" json:"protocol,omitempty"` +} + +func (m *TunnelEncapSubTLVProtocol) Reset() { *m = TunnelEncapSubTLVProtocol{} } +func (m *TunnelEncapSubTLVProtocol) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapSubTLVProtocol) ProtoMessage() {} +func (*TunnelEncapSubTLVProtocol) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{58} } + +func (m *TunnelEncapSubTLVProtocol) GetProtocol() uint32 { + if m != nil { + return m.Protocol + } + return 0 +} + +type TunnelEncapSubTLVColor struct { + Color uint32 `protobuf:"varint,1,opt,name=color" json:"color,omitempty"` +} + +func (m *TunnelEncapSubTLVColor) Reset() { *m = TunnelEncapSubTLVColor{} } +func (m *TunnelEncapSubTLVColor) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapSubTLVColor) ProtoMessage() {} +func (*TunnelEncapSubTLVColor) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{59} } + +func (m *TunnelEncapSubTLVColor) GetColor() uint32 { + if m != nil { + return m.Color + } + return 0 +} + +type TunnelEncapSubTLVUnknown struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *TunnelEncapSubTLVUnknown) Reset() { *m = TunnelEncapSubTLVUnknown{} } +func (m *TunnelEncapSubTLVUnknown) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapSubTLVUnknown) ProtoMessage() {} +func (*TunnelEncapSubTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{60} } + +func (m *TunnelEncapSubTLVUnknown) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *TunnelEncapSubTLVUnknown) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type TunnelEncapTLV struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + // Each TLV must be one of: + // - TunnelEncapSubTLVEncapsulation + // - TunnelEncapSubTLVProtocol + // - TunnelEncapSubTLVColor + // - TunnelEncapSubTLVUnknown + Tlvs []*google_protobuf.Any `protobuf:"bytes,2,rep,name=tlvs" json:"tlvs,omitempty"` +} + +func (m *TunnelEncapTLV) Reset() { *m = TunnelEncapTLV{} } +func (m *TunnelEncapTLV) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapTLV) ProtoMessage() {} +func (*TunnelEncapTLV) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{61} } + +func (m *TunnelEncapTLV) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *TunnelEncapTLV) GetTlvs() []*google_protobuf.Any { + if m != nil { + return m.Tlvs + } + return nil +} + +type TunnelEncapAttribute struct { + Tlvs []*TunnelEncapTLV `protobuf:"bytes,1,rep,name=tlvs" json:"tlvs,omitempty"` +} + +func (m *TunnelEncapAttribute) Reset() { *m = TunnelEncapAttribute{} } +func (m *TunnelEncapAttribute) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapAttribute) ProtoMessage() {} +func (*TunnelEncapAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{62} } + +func (m *TunnelEncapAttribute) GetTlvs() []*TunnelEncapTLV { + if m != nil { + return m.Tlvs + } + return nil +} + +type IPv6AddressSpecificExtended struct { + IsTransitive bool `protobuf:"varint,1,opt,name=is_transitive,json=isTransitive" json:"is_transitive,omitempty"` + SubType uint32 `protobuf:"varint,2,opt,name=sub_type,json=subType" json:"sub_type,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"` + LocalAdmin uint32 `protobuf:"varint,4,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *IPv6AddressSpecificExtended) Reset() { *m = IPv6AddressSpecificExtended{} } +func (m *IPv6AddressSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*IPv6AddressSpecificExtended) ProtoMessage() {} +func (*IPv6AddressSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{63} } + +func (m *IPv6AddressSpecificExtended) GetIsTransitive() bool { + if m != nil { + return m.IsTransitive + } + return false +} + +func (m *IPv6AddressSpecificExtended) GetSubType() uint32 { + if m != nil { + return m.SubType + } + return 0 +} + +func (m *IPv6AddressSpecificExtended) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *IPv6AddressSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type RedirectIPv6AddressSpecificExtended struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + LocalAdmin uint32 `protobuf:"varint,2,opt,name=local_admin,json=localAdmin" json:"local_admin,omitempty"` +} + +func (m *RedirectIPv6AddressSpecificExtended) Reset() { *m = RedirectIPv6AddressSpecificExtended{} } +func (m *RedirectIPv6AddressSpecificExtended) String() string { return proto.CompactTextString(m) } +func (*RedirectIPv6AddressSpecificExtended) ProtoMessage() {} +func (*RedirectIPv6AddressSpecificExtended) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{64} +} + +func (m *RedirectIPv6AddressSpecificExtended) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *RedirectIPv6AddressSpecificExtended) GetLocalAdmin() uint32 { + if m != nil { + return m.LocalAdmin + } + return 0 +} + +type IP6ExtendedCommunitiesAttribute struct { + // Each Community must be one of: + // - IPv6AddressSpecificExtended + // - RedirectIPv6AddressSpecificExtended + Communities []*google_protobuf.Any `protobuf:"bytes,1,rep,name=communities" json:"communities,omitempty"` +} + +func (m *IP6ExtendedCommunitiesAttribute) Reset() { *m = IP6ExtendedCommunitiesAttribute{} } +func (m *IP6ExtendedCommunitiesAttribute) String() string { return proto.CompactTextString(m) } +func (*IP6ExtendedCommunitiesAttribute) ProtoMessage() {} +func (*IP6ExtendedCommunitiesAttribute) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{65} +} + +func (m *IP6ExtendedCommunitiesAttribute) GetCommunities() []*google_protobuf.Any { + if m != nil { + return m.Communities + } + return nil +} + +type AigpTLVIGPMetric struct { + Metric uint64 `protobuf:"varint,1,opt,name=metric" json:"metric,omitempty"` +} + +func (m *AigpTLVIGPMetric) Reset() { *m = AigpTLVIGPMetric{} } +func (m *AigpTLVIGPMetric) String() string { return proto.CompactTextString(m) } +func (*AigpTLVIGPMetric) ProtoMessage() {} +func (*AigpTLVIGPMetric) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{66} } + +func (m *AigpTLVIGPMetric) GetMetric() uint64 { + if m != nil { + return m.Metric + } + return 0 +} + +type AigpTLVUnknown struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *AigpTLVUnknown) Reset() { *m = AigpTLVUnknown{} } +func (m *AigpTLVUnknown) String() string { return proto.CompactTextString(m) } +func (*AigpTLVUnknown) ProtoMessage() {} +func (*AigpTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{67} } + +func (m *AigpTLVUnknown) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *AigpTLVUnknown) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type AigpAttribute struct { + // Each TLV must be one of: + // - AigpTLVIGPMetric + // - AigpTLVUnknown + Tlvs []*google_protobuf.Any `protobuf:"bytes,1,rep,name=tlvs" json:"tlvs,omitempty"` +} + +func (m *AigpAttribute) Reset() { *m = AigpAttribute{} } +func (m *AigpAttribute) String() string { return proto.CompactTextString(m) } +func (*AigpAttribute) ProtoMessage() {} +func (*AigpAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{68} } + +func (m *AigpAttribute) GetTlvs() []*google_protobuf.Any { + if m != nil { + return m.Tlvs + } + return nil +} + +type LargeCommunity struct { + GlobalAdmin uint32 `protobuf:"varint,1,opt,name=global_admin,json=globalAdmin" json:"global_admin,omitempty"` + LocalData1 uint32 `protobuf:"varint,2,opt,name=local_data1,json=localData1" json:"local_data1,omitempty"` + LocalData2 uint32 `protobuf:"varint,3,opt,name=local_data2,json=localData2" json:"local_data2,omitempty"` +} + +func (m *LargeCommunity) Reset() { *m = LargeCommunity{} } +func (m *LargeCommunity) String() string { return proto.CompactTextString(m) } +func (*LargeCommunity) ProtoMessage() {} +func (*LargeCommunity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{69} } + +func (m *LargeCommunity) GetGlobalAdmin() uint32 { + if m != nil { + return m.GlobalAdmin + } + return 0 +} + +func (m *LargeCommunity) GetLocalData1() uint32 { + if m != nil { + return m.LocalData1 + } + return 0 +} + +func (m *LargeCommunity) GetLocalData2() uint32 { + if m != nil { + return m.LocalData2 + } + return 0 +} + +type LargeCommunitiesAttribute struct { + Communities []*LargeCommunity `protobuf:"bytes,1,rep,name=communities" json:"communities,omitempty"` +} + +func (m *LargeCommunitiesAttribute) Reset() { *m = LargeCommunitiesAttribute{} } +func (m *LargeCommunitiesAttribute) String() string { return proto.CompactTextString(m) } +func (*LargeCommunitiesAttribute) ProtoMessage() {} +func (*LargeCommunitiesAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{70} } + +func (m *LargeCommunitiesAttribute) GetCommunities() []*LargeCommunity { + if m != nil { + return m.Communities + } + return nil +} + +type UnknownAttribute struct { + Flags uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` + Type uint32 `protobuf:"varint,2,opt,name=type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *UnknownAttribute) Reset() { *m = UnknownAttribute{} } +func (m *UnknownAttribute) String() string { return proto.CompactTextString(m) } +func (*UnknownAttribute) ProtoMessage() {} +func (*UnknownAttribute) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{71} } + +func (m *UnknownAttribute) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +func (m *UnknownAttribute) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +func (m *UnknownAttribute) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*OriginAttribute)(nil), "gobgpapi.OriginAttribute") + proto.RegisterType((*AsSegment)(nil), "gobgpapi.AsSegment") + proto.RegisterType((*AsPathAttribute)(nil), "gobgpapi.AsPathAttribute") + proto.RegisterType((*NextHopAttribute)(nil), "gobgpapi.NextHopAttribute") + proto.RegisterType((*MultiExitDiscAttribute)(nil), "gobgpapi.MultiExitDiscAttribute") + proto.RegisterType((*LocalPrefAttribute)(nil), "gobgpapi.LocalPrefAttribute") + proto.RegisterType((*AtomicAggregateAttribute)(nil), "gobgpapi.AtomicAggregateAttribute") + proto.RegisterType((*AggregatorAttribute)(nil), "gobgpapi.AggregatorAttribute") + proto.RegisterType((*CommunitiesAttribute)(nil), "gobgpapi.CommunitiesAttribute") + proto.RegisterType((*OriginatorIdAttribute)(nil), "gobgpapi.OriginatorIdAttribute") + proto.RegisterType((*ClusterListAttribute)(nil), "gobgpapi.ClusterListAttribute") + proto.RegisterType((*IPAddressPrefix)(nil), "gobgpapi.IPAddressPrefix") + proto.RegisterType((*LabeledIPAddressPrefix)(nil), "gobgpapi.LabeledIPAddressPrefix") + proto.RegisterType((*EncapsulationNLRI)(nil), "gobgpapi.EncapsulationNLRI") + proto.RegisterType((*RouteDistinguisherTwoOctetAS)(nil), "gobgpapi.RouteDistinguisherTwoOctetAS") + proto.RegisterType((*RouteDistinguisherIPAddress)(nil), "gobgpapi.RouteDistinguisherIPAddress") + proto.RegisterType((*RouteDistinguisherFourOctetAS)(nil), "gobgpapi.RouteDistinguisherFourOctetAS") + proto.RegisterType((*EthernetSegmentIdentifier)(nil), "gobgpapi.EthernetSegmentIdentifier") + proto.RegisterType((*EVPNEthernetAutoDiscoveryRoute)(nil), "gobgpapi.EVPNEthernetAutoDiscoveryRoute") + proto.RegisterType((*EVPNMACIPAdvertisementRoute)(nil), "gobgpapi.EVPNMACIPAdvertisementRoute") + proto.RegisterType((*EVPNInclusiveMulticastEthernetTagRoute)(nil), "gobgpapi.EVPNInclusiveMulticastEthernetTagRoute") + proto.RegisterType((*EVPNEthernetSegmentRoute)(nil), "gobgpapi.EVPNEthernetSegmentRoute") + proto.RegisterType((*EVPNIPPrefixRoute)(nil), "gobgpapi.EVPNIPPrefixRoute") + proto.RegisterType((*LabeledVPNIPAddressPrefix)(nil), "gobgpapi.LabeledVPNIPAddressPrefix") + proto.RegisterType((*RouteTargetMembershipNLRI)(nil), "gobgpapi.RouteTargetMembershipNLRI") + proto.RegisterType((*FlowSpecIPPrefix)(nil), "gobgpapi.FlowSpecIPPrefix") + proto.RegisterType((*FlowSpecMAC)(nil), "gobgpapi.FlowSpecMAC") + proto.RegisterType((*FlowSpecComponentItem)(nil), "gobgpapi.FlowSpecComponentItem") + proto.RegisterType((*FlowSpecComponent)(nil), "gobgpapi.FlowSpecComponent") + proto.RegisterType((*FlowSpecNLRI)(nil), "gobgpapi.FlowSpecNLRI") + proto.RegisterType((*VPNFlowSpecNLRI)(nil), "gobgpapi.VPNFlowSpecNLRI") + proto.RegisterType((*OpaqueNLRI)(nil), "gobgpapi.OpaqueNLRI") + proto.RegisterType((*MpReachNLRIAttribute)(nil), "gobgpapi.MpReachNLRIAttribute") + proto.RegisterType((*MpUnreachNLRIAttribute)(nil), "gobgpapi.MpUnreachNLRIAttribute") + proto.RegisterType((*TwoOctetAsSpecificExtended)(nil), "gobgpapi.TwoOctetAsSpecificExtended") + proto.RegisterType((*IPv4AddressSpecificExtended)(nil), "gobgpapi.IPv4AddressSpecificExtended") + proto.RegisterType((*FourOctetAsSpecificExtended)(nil), "gobgpapi.FourOctetAsSpecificExtended") + proto.RegisterType((*ValidationExtended)(nil), "gobgpapi.ValidationExtended") + proto.RegisterType((*ColorExtended)(nil), "gobgpapi.ColorExtended") + proto.RegisterType((*EncapExtended)(nil), "gobgpapi.EncapExtended") + proto.RegisterType((*DefaultGatewayExtended)(nil), "gobgpapi.DefaultGatewayExtended") + proto.RegisterType((*OpaqueExtended)(nil), "gobgpapi.OpaqueExtended") + proto.RegisterType((*ESILabelExtended)(nil), "gobgpapi.ESILabelExtended") + proto.RegisterType((*ESImportRouteTarget)(nil), "gobgpapi.ESImportRouteTarget") + proto.RegisterType((*MacMobilityExtended)(nil), "gobgpapi.MacMobilityExtended") + proto.RegisterType((*RouterMacExtended)(nil), "gobgpapi.RouterMacExtended") + proto.RegisterType((*TrafficRateExtended)(nil), "gobgpapi.TrafficRateExtended") + proto.RegisterType((*TrafficActionExtended)(nil), "gobgpapi.TrafficActionExtended") + proto.RegisterType((*RedirectTwoOctetAsSpecificExtended)(nil), "gobgpapi.RedirectTwoOctetAsSpecificExtended") + proto.RegisterType((*RedirectIPv4AddressSpecificExtended)(nil), "gobgpapi.RedirectIPv4AddressSpecificExtended") + proto.RegisterType((*RedirectFourOctetAsSpecificExtended)(nil), "gobgpapi.RedirectFourOctetAsSpecificExtended") + proto.RegisterType((*TrafficRemarkExtended)(nil), "gobgpapi.TrafficRemarkExtended") + proto.RegisterType((*UnknownExtended)(nil), "gobgpapi.UnknownExtended") + proto.RegisterType((*ExtendedCommunitiesAttribute)(nil), "gobgpapi.ExtendedCommunitiesAttribute") + proto.RegisterType((*As4PathAttribute)(nil), "gobgpapi.As4PathAttribute") + proto.RegisterType((*As4AggregatorAttribute)(nil), "gobgpapi.As4AggregatorAttribute") + proto.RegisterType((*PmsiTunnelAttribute)(nil), "gobgpapi.PmsiTunnelAttribute") + proto.RegisterType((*TunnelEncapSubTLVEncapsulation)(nil), "gobgpapi.TunnelEncapSubTLVEncapsulation") + proto.RegisterType((*TunnelEncapSubTLVProtocol)(nil), "gobgpapi.TunnelEncapSubTLVProtocol") + proto.RegisterType((*TunnelEncapSubTLVColor)(nil), "gobgpapi.TunnelEncapSubTLVColor") + proto.RegisterType((*TunnelEncapSubTLVUnknown)(nil), "gobgpapi.TunnelEncapSubTLVUnknown") + proto.RegisterType((*TunnelEncapTLV)(nil), "gobgpapi.TunnelEncapTLV") + proto.RegisterType((*TunnelEncapAttribute)(nil), "gobgpapi.TunnelEncapAttribute") + proto.RegisterType((*IPv6AddressSpecificExtended)(nil), "gobgpapi.IPv6AddressSpecificExtended") + proto.RegisterType((*RedirectIPv6AddressSpecificExtended)(nil), "gobgpapi.RedirectIPv6AddressSpecificExtended") + proto.RegisterType((*IP6ExtendedCommunitiesAttribute)(nil), "gobgpapi.IP6ExtendedCommunitiesAttribute") + proto.RegisterType((*AigpTLVIGPMetric)(nil), "gobgpapi.AigpTLVIGPMetric") + proto.RegisterType((*AigpTLVUnknown)(nil), "gobgpapi.AigpTLVUnknown") + proto.RegisterType((*AigpAttribute)(nil), "gobgpapi.AigpAttribute") + proto.RegisterType((*LargeCommunity)(nil), "gobgpapi.LargeCommunity") + proto.RegisterType((*LargeCommunitiesAttribute)(nil), "gobgpapi.LargeCommunitiesAttribute") + proto.RegisterType((*UnknownAttribute)(nil), "gobgpapi.UnknownAttribute") +} + +func init() { proto.RegisterFile("attribute.proto", fileDescriptor1) } + +var fileDescriptor1 = []byte{ + // 1868 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xeb, 0x6f, 0x1b, 0xc7, + 0x11, 0x07, 0x8f, 0x94, 0x4c, 0x0e, 0x45, 0x49, 0xa6, 0x64, 0x81, 0x92, 0xe2, 0xc8, 0x5d, 0x37, + 0xad, 0xea, 0x36, 0x72, 0xab, 0x38, 0x6e, 0xed, 0xa0, 0x28, 0x18, 0x49, 0x49, 0xd8, 0x88, 0x32, + 0x73, 0x92, 0x55, 0x14, 0x28, 0xca, 0x2e, 0xef, 0x96, 0xa7, 0x85, 0xee, 0x95, 0xdb, 0x3d, 0x3d, + 0xfe, 0x84, 0x7e, 0x68, 0x91, 0x4f, 0x45, 0xff, 0x92, 0xfe, 0x67, 0xfd, 0x5e, 0xec, 0xeb, 0x1e, + 0xa2, 0xa8, 0x87, 0x53, 0x03, 0xfe, 0xb6, 0xb3, 0x9c, 0x9d, 0x99, 0xfd, 0xed, 0xcc, 0x6f, 0x86, + 0x07, 0x0b, 0x98, 0xf3, 0x84, 0x8e, 0x52, 0x4e, 0xb6, 0xe2, 0x24, 0xe2, 0x51, 0xbb, 0xee, 0x45, + 0x23, 0x2f, 0xc6, 0x31, 0x5d, 0x5b, 0xf5, 0xa2, 0xc8, 0xf3, 0xc9, 0x73, 0xb9, 0x3f, 0x4a, 0xc7, + 0xcf, 0x71, 0x78, 0xa9, 0x94, 0xd0, 0x2f, 0x60, 0xe1, 0x4d, 0x42, 0x3d, 0x1a, 0x76, 0xcd, 0xe9, + 0xf6, 0x0a, 0xcc, 0x46, 0x72, 0xab, 0x53, 0x79, 0x52, 0xd9, 0x6c, 0xd9, 0x5a, 0x42, 0xaf, 0xa0, + 0xd1, 0x65, 0x87, 0xc4, 0x0b, 0x48, 0xc8, 0xdb, 0x6d, 0xa8, 0xf1, 0xcb, 0x98, 0x68, 0x15, 0xb9, + 0x6e, 0x77, 0xe0, 0x41, 0x98, 0x06, 0x23, 0x92, 0xb0, 0x8e, 0xf5, 0xa4, 0xba, 0xd9, 0xb2, 0x8d, + 0x88, 0xbe, 0x84, 0x85, 0x2e, 0x1b, 0x60, 0x7e, 0x92, 0x7b, 0x79, 0x0e, 0x75, 0xa6, 0x6c, 0xb1, + 0x4e, 0xe5, 0x49, 0x75, 0xb3, 0xb9, 0xbd, 0xb4, 0x65, 0x02, 0xde, 0xca, 0xfc, 0xd8, 0x99, 0x12, + 0xfa, 0x14, 0x16, 0x0f, 0xc8, 0x05, 0xff, 0x26, 0x8a, 0x73, 0x23, 0xab, 0x50, 0x0f, 0xc9, 0x05, + 0x1f, 0x9e, 0x44, 0xb1, 0x8c, 0xa4, 0x61, 0x3f, 0x08, 0x95, 0x0e, 0x7a, 0x06, 0x2b, 0xfd, 0xd4, + 0xe7, 0x74, 0xef, 0x82, 0xf2, 0x5d, 0xca, 0x9c, 0xfc, 0xd0, 0x22, 0x54, 0x03, 0xe2, 0xea, 0xc8, + 0xc5, 0x12, 0x7d, 0x06, 0xed, 0xfd, 0xc8, 0xc1, 0xfe, 0x20, 0x21, 0xe3, 0x5c, 0xef, 0x31, 0x80, + 0x2f, 0x76, 0x87, 0x71, 0x42, 0xc6, 0x5a, 0xbd, 0xe1, 0x1b, 0x3d, 0xb4, 0x06, 0x9d, 0x2e, 0x8f, + 0x02, 0xea, 0x74, 0x3d, 0x2f, 0x21, 0x1e, 0xe6, 0x24, 0x3b, 0x8a, 0xfe, 0x00, 0x4b, 0x66, 0x37, + 0x4a, 0x72, 0x8b, 0xf3, 0x60, 0x61, 0x81, 0x8d, 0xb0, 0x64, 0x61, 0x26, 0x00, 0xc3, 0xae, 0x9b, + 0x10, 0xc6, 0x3a, 0x55, 0x15, 0xbd, 0x16, 0xd1, 0xef, 0x60, 0x79, 0x27, 0x0a, 0x82, 0x34, 0xa4, + 0x9c, 0x12, 0x96, 0x5b, 0x78, 0x02, 0x4d, 0x27, 0xdf, 0x97, 0xc0, 0xb5, 0xec, 0xe2, 0x16, 0xfa, + 0x39, 0x3c, 0x52, 0x0f, 0x2a, 0x5c, 0xf7, 0xdc, 0x92, 0x73, 0xea, 0x6a, 0x94, 0x2c, 0xea, 0xa2, + 0x4d, 0x58, 0xde, 0xf1, 0x53, 0xc6, 0x49, 0xb2, 0x4f, 0x19, 0x2f, 0xc1, 0x43, 0x5d, 0x65, 0xba, + 0x61, 0x8b, 0x25, 0xfa, 0x06, 0x16, 0x7a, 0x83, 0xae, 0x8a, 0x4c, 0x5c, 0x9d, 0x5e, 0x08, 0x6c, + 0x62, 0xb9, 0x1a, 0xfa, 0xc4, 0xe4, 0x49, 0x43, 0xed, 0xec, 0x93, 0x50, 0xa4, 0x90, 0x12, 0xe4, + 0x65, 0x1b, 0xb6, 0x96, 0x90, 0x07, 0x2b, 0xfb, 0x78, 0x44, 0x7c, 0xe2, 0x5e, 0x35, 0xb8, 0x02, + 0xb3, 0xbe, 0xf8, 0xc5, 0xdc, 0x49, 0x4b, 0x57, 0x1c, 0x59, 0xd3, 0x1d, 0x55, 0x4b, 0x8e, 0x3e, + 0x85, 0x87, 0x7b, 0xa1, 0x83, 0x63, 0x96, 0xfa, 0x98, 0xd3, 0x28, 0x3c, 0xd8, 0xb7, 0x7b, 0x45, + 0xb8, 0x2b, 0x65, 0xb8, 0x07, 0xf0, 0x91, 0x1d, 0xa5, 0x9c, 0xec, 0x52, 0xc6, 0x69, 0xe8, 0xa5, + 0x94, 0x9d, 0x90, 0xe4, 0xe8, 0x3c, 0x7a, 0xe3, 0x70, 0xc2, 0xbb, 0x87, 0xed, 0x65, 0x98, 0xc1, + 0x6e, 0x90, 0x55, 0x84, 0x12, 0xda, 0x6b, 0x50, 0xc7, 0x8c, 0x51, 0x2f, 0x24, 0xae, 0x8e, 0x2c, + 0x93, 0xd1, 0x1b, 0x58, 0x9f, 0xb4, 0x98, 0x5d, 0xba, 0x6c, 0xb0, 0x71, 0x17, 0x83, 0xdf, 0xc1, + 0xe3, 0x49, 0x83, 0x5f, 0x45, 0x69, 0xf2, 0xee, 0x31, 0xee, 0xc1, 0xea, 0x1e, 0x3f, 0x21, 0x49, + 0x48, 0xb8, 0x2e, 0xb7, 0x9e, 0x4b, 0x42, 0x4e, 0xc7, 0x94, 0x24, 0xd7, 0x16, 0xf8, 0x32, 0xcc, + 0x9c, 0x61, 0x3f, 0x25, 0xd2, 0xd2, 0x9c, 0xad, 0x04, 0xf4, 0x9f, 0x0a, 0x7c, 0xbc, 0x77, 0x3c, + 0x38, 0x30, 0xb6, 0xba, 0x29, 0x8f, 0x44, 0xc5, 0x45, 0x67, 0x24, 0xb9, 0x94, 0x31, 0xb7, 0x7f, + 0x0a, 0x56, 0xa2, 0x72, 0xaf, 0xb9, 0xbd, 0xbc, 0xa5, 0xd8, 0x68, 0xcb, 0xb0, 0xd1, 0x56, 0x37, + 0xbc, 0xb4, 0xad, 0xc4, 0x6d, 0x7f, 0x0e, 0x55, 0xc2, 0xa8, 0x34, 0xde, 0xdc, 0x7e, 0x9a, 0xb3, + 0xc1, 0xd4, 0x20, 0x6d, 0xa1, 0xdf, 0xfe, 0x09, 0xcc, 0x11, 0xad, 0x31, 0xe4, 0xd8, 0x93, 0x99, + 0xd0, 0xb2, 0x9b, 0x66, 0xef, 0x08, 0x7b, 0x22, 0x70, 0x99, 0x4f, 0x9d, 0x9a, 0xc2, 0x46, 0x0a, + 0xe8, 0xbf, 0x15, 0x58, 0x17, 0x81, 0xf7, 0xbb, 0x3b, 0xe2, 0x65, 0xce, 0x48, 0xc2, 0x29, 0x23, + 0x92, 0x76, 0x3e, 0x88, 0xa8, 0x37, 0xa0, 0x19, 0x60, 0x67, 0x68, 0x72, 0xb6, 0x26, 0x53, 0x05, + 0x02, 0xec, 0x98, 0x2c, 0x7a, 0x0c, 0x40, 0xe3, 0xec, 0xf7, 0x19, 0xf9, 0x7b, 0x83, 0xc6, 0xe6, + 0xe7, 0xbc, 0xa6, 0x66, 0x8b, 0x35, 0x85, 0x7e, 0xa8, 0xc0, 0xcf, 0xc4, 0xbd, 0x7b, 0xa1, 0xe3, + 0xa7, 0x8c, 0x9e, 0x11, 0x49, 0x94, 0x0e, 0x66, 0x7c, 0x2f, 0xf7, 0x7e, 0x1f, 0x08, 0xae, 0xde, + 0xc5, 0x9a, 0xbc, 0x4b, 0x39, 0xd4, 0xea, 0x95, 0x50, 0xd1, 0xbf, 0x2a, 0xd0, 0x29, 0xe6, 0x90, + 0xa1, 0xff, 0xf7, 0xff, 0x0e, 0xb7, 0x04, 0xf6, 0x77, 0x0b, 0x1e, 0x4a, 0xac, 0x06, 0x8a, 0xa8, + 0x3e, 0x8c, 0xcc, 0x58, 0x87, 0x06, 0x8d, 0x87, 0x9a, 0xf9, 0x54, 0x5e, 0xd4, 0x69, 0xac, 0xa9, + 0x14, 0x41, 0x2b, 0xfb, 0x51, 0xb2, 0xe6, 0x8c, 0x32, 0x60, 0x14, 0x04, 0x6f, 0x3e, 0x06, 0xf0, + 0xce, 0xb3, 0x5b, 0xcf, 0xaa, 0x5b, 0x7b, 0xe7, 0x05, 0x7a, 0x52, 0xf5, 0xf2, 0xa0, 0x58, 0x2f, + 0x3f, 0x54, 0x60, 0x55, 0xd3, 0xb7, 0x44, 0xe4, 0x6e, 0x0c, 0xae, 0xb0, 0xb2, 0x6e, 0xc1, 0xaa, + 0xcc, 0xf3, 0xd5, 0xe9, 0x3c, 0x5f, 0x2b, 0xf1, 0xfc, 0x77, 0xb0, 0x2a, 0x5f, 0xe4, 0x08, 0x27, + 0x1e, 0xe1, 0x7d, 0x22, 0xc7, 0x8d, 0x13, 0x1a, 0x4b, 0xbe, 0x57, 0xed, 0xb6, 0x92, 0xb5, 0x5b, + 0x11, 0x09, 0xbf, 0x25, 0x12, 0x8e, 0x52, 0x58, 0xfc, 0xca, 0x8f, 0xce, 0x0f, 0x63, 0xe2, 0x98, + 0x47, 0xbf, 0x96, 0x0c, 0xdf, 0xad, 0x33, 0xc9, 0xe9, 0x6a, 0x3c, 0x66, 0x84, 0x6b, 0x2e, 0xd2, + 0x12, 0xfa, 0x02, 0x9a, 0xc6, 0x6d, 0xbf, 0xbb, 0x33, 0x6d, 0xbe, 0x32, 0x2f, 0x66, 0x95, 0xfb, + 0xd7, 0xef, 0xe1, 0x91, 0x39, 0xbc, 0x13, 0x05, 0x71, 0x14, 0x8a, 0xb4, 0xe2, 0x24, 0x10, 0x10, + 0xe8, 0xd1, 0xa8, 0x65, 0x5b, 0x51, 0x5c, 0x66, 0xf0, 0x9a, 0x61, 0xf0, 0xbf, 0xc2, 0xc3, 0x89, + 0xe3, 0xd7, 0x46, 0xf0, 0x39, 0xcc, 0x50, 0x4e, 0x02, 0x35, 0xdf, 0x35, 0xb7, 0x37, 0xf2, 0x9c, + 0xbe, 0xd6, 0xbd, 0xad, 0xb4, 0xd1, 0x6b, 0x98, 0x33, 0xbf, 0xcb, 0x87, 0x79, 0x06, 0x33, 0x49, + 0xea, 0x13, 0x33, 0xf8, 0x5d, 0xff, 0x16, 0x4a, 0x05, 0x39, 0xb0, 0x70, 0x3c, 0x38, 0x28, 0x1d, + 0xbf, 0x5b, 0xf5, 0x65, 0x4e, 0xac, 0xdb, 0x9d, 0xbc, 0x00, 0x78, 0x13, 0xe3, 0xef, 0x53, 0x22, + 0xed, 0x2f, 0x42, 0xf5, 0x94, 0x5c, 0x4a, 0x07, 0x73, 0xb6, 0x58, 0x4e, 0x69, 0x7c, 0xe7, 0xb0, + 0xdc, 0x8f, 0x6d, 0x82, 0x9d, 0x13, 0x71, 0xac, 0x34, 0x40, 0x8f, 0x71, 0x40, 0xfd, 0x4b, 0x33, + 0x40, 0x2b, 0x49, 0x54, 0xad, 0x99, 0x56, 0x55, 0x54, 0x0d, 0xbb, 0xae, 0xc7, 0x55, 0x26, 0xc2, + 0x0d, 0xfd, 0x84, 0x0a, 0x0a, 0xba, 0x21, 0x5c, 0xa9, 0x82, 0xfe, 0x02, 0x2b, 0xfd, 0xf8, 0x6d, + 0x98, 0xdc, 0xdd, 0xf5, 0x7d, 0xac, 0xff, 0xa3, 0x02, 0x6b, 0xd9, 0xec, 0xc3, 0x04, 0xea, 0x74, + 0x4c, 0x9d, 0xbd, 0x0b, 0x4e, 0x42, 0x97, 0xb8, 0xed, 0xa7, 0xd0, 0xa2, 0x6c, 0xc8, 0x13, 0x1c, + 0x32, 0xca, 0xe9, 0x99, 0x4a, 0x90, 0xba, 0x3d, 0x47, 0xd9, 0x51, 0xb6, 0x27, 0x06, 0x73, 0x96, + 0x8e, 0x86, 0x32, 0x81, 0x54, 0x69, 0x3c, 0x60, 0xe9, 0xe8, 0x48, 0xe4, 0x90, 0xaa, 0xca, 0x6a, + 0x56, 0x95, 0x1b, 0xd0, 0x54, 0x63, 0xb6, 0x9a, 0x5e, 0x54, 0x55, 0xa8, 0xc9, 0xbb, 0x2b, 0x76, + 0xd0, 0xbf, 0x2b, 0xb0, 0xde, 0x1b, 0x9c, 0xbd, 0xd0, 0x74, 0xf3, 0x7f, 0x0f, 0x68, 0xea, 0x14, + 0x7e, 0x7b, 0x68, 0xff, 0xac, 0xc0, 0x7a, 0x3e, 0x83, 0x7d, 0x00, 0x58, 0x3d, 0x83, 0xf6, 0x31, + 0xf6, 0xa9, 0x2b, 0x87, 0xde, 0x2c, 0x8c, 0x65, 0x98, 0x61, 0x1c, 0x73, 0x53, 0xcb, 0x4a, 0x40, + 0x9f, 0x40, 0x6b, 0x27, 0xf2, 0xa3, 0xa4, 0xa8, 0xe6, 0x88, 0x0d, 0xa3, 0x26, 0x05, 0xf4, 0x6b, + 0x68, 0xc9, 0x51, 0x3a, 0x53, 0xdb, 0x80, 0x26, 0x4f, 0xc3, 0x90, 0xf8, 0xc3, 0x02, 0x3f, 0x80, + 0xda, 0x12, 0x51, 0xa3, 0x0e, 0xac, 0xec, 0x92, 0x31, 0x4e, 0x7d, 0xfe, 0x35, 0xe6, 0xe4, 0x1c, + 0x5f, 0x9a, 0xa3, 0xe8, 0x5b, 0x98, 0x57, 0x75, 0x76, 0x3f, 0x84, 0xb2, 0xf2, 0xab, 0x16, 0xcb, + 0xcf, 0x86, 0xc5, 0xbd, 0xc3, 0x9e, 0x6c, 0x48, 0x99, 0xb9, 0x4d, 0x58, 0xa4, 0x6c, 0xc8, 0x68, + 0xe8, 0xf9, 0x64, 0x88, 0x9d, 0x82, 0xc5, 0x79, 0xca, 0x0e, 0xe5, 0x76, 0xd7, 0x31, 0x36, 0x55, + 0x8b, 0xb3, 0x8a, 0x2d, 0x6e, 0x1b, 0x96, 0xf6, 0x0e, 0x7b, 0x41, 0x1c, 0x25, 0xbc, 0xd0, 0x57, + 0x44, 0xe5, 0x12, 0x36, 0xa4, 0x72, 0x5f, 0x8f, 0xec, 0x75, 0xc2, 0x94, 0x1e, 0x7a, 0x0b, 0x4b, + 0x7d, 0xec, 0xf4, 0xa3, 0x11, 0xf5, 0x29, 0xcf, 0xee, 0x2a, 0x7b, 0x34, 0x1b, 0x32, 0x4e, 0x9d, + 0xd3, 0x4b, 0x1d, 0x43, 0x9d, 0xb2, 0x43, 0x29, 0x8b, 0x1e, 0xcf, 0xc8, 0xf7, 0x29, 0x09, 0x1d, + 0x32, 0x0c, 0xd3, 0xc0, 0x4c, 0x4c, 0x66, 0xef, 0x20, 0x0d, 0xd0, 0x27, 0xf0, 0x50, 0x86, 0x90, + 0xf4, 0x71, 0x9e, 0x50, 0xe2, 0xbf, 0x2b, 0x76, 0x74, 0x08, 0x62, 0x89, 0x5e, 0xc1, 0xd2, 0x51, + 0x82, 0xc7, 0x63, 0xea, 0xd8, 0x98, 0xe7, 0xb8, 0x5e, 0xed, 0x7d, 0x6d, 0xa8, 0x25, 0x22, 0x03, + 0x84, 0x23, 0xcb, 0x96, 0x6b, 0xf4, 0x2d, 0x3c, 0xd2, 0x47, 0x05, 0x26, 0x85, 0x7c, 0x59, 0x83, + 0x3a, 0x27, 0x49, 0x40, 0x43, 0xec, 0x9b, 0xc8, 0x8d, 0x2c, 0x18, 0x86, 0xe1, 0x20, 0xf6, 0x95, + 0xa9, 0xba, 0xad, 0x25, 0xf4, 0x16, 0x90, 0x4d, 0x5c, 0x9a, 0x10, 0x87, 0xdf, 0x40, 0x1e, 0x57, + 0xc3, 0xba, 0x92, 0xd0, 0xd6, 0x44, 0x42, 0xff, 0x0d, 0x9e, 0x1a, 0xb3, 0x37, 0x71, 0xc0, 0xd4, + 0xbf, 0x76, 0xb7, 0x7b, 0x38, 0xce, 0x3d, 0xdc, 0x54, 0xca, 0xf7, 0x8e, 0xfc, 0x97, 0x19, 0xba, + 0x36, 0x09, 0x70, 0x72, 0x9a, 0x59, 0x6a, 0x43, 0xcd, 0x65, 0x8e, 0xe9, 0xca, 0x72, 0x8d, 0xbe, + 0x80, 0x85, 0xb7, 0xe1, 0x69, 0x18, 0x9d, 0x87, 0x45, 0xb5, 0x3b, 0xfe, 0x01, 0x3b, 0x86, 0x8f, + 0xcc, 0xa9, 0x6b, 0x3f, 0x1a, 0xbc, 0x9c, 0xfc, 0x68, 0x30, 0xad, 0x05, 0x94, 0x3e, 0x25, 0xec, + 0xc0, 0x62, 0x97, 0xbd, 0xf8, 0x91, 0x9f, 0x6d, 0xbe, 0x84, 0x95, 0x2e, 0x7b, 0xf1, 0xe3, 0xbe, + 0x86, 0x10, 0x58, 0x1a, 0x04, 0x8c, 0x1e, 0x49, 0x8a, 0xc9, 0x0d, 0x2c, 0xc3, 0xcc, 0xd8, 0xc7, + 0x9e, 0x79, 0x15, 0x25, 0x64, 0xb8, 0x59, 0x65, 0xdc, 0x54, 0xb1, 0x57, 0x0b, 0xc5, 0xae, 0xbf, + 0x88, 0xd4, 0x24, 0x94, 0x16, 0x75, 0xd1, 0x1f, 0xe1, 0x63, 0xe5, 0x42, 0xf2, 0xdd, 0x61, 0x3a, + 0x3a, 0xda, 0x3f, 0x2e, 0x7d, 0x45, 0x28, 0x4e, 0x06, 0x2d, 0x35, 0x19, 0xac, 0xc0, 0xac, 0x13, + 0x45, 0xa7, 0xd4, 0x3c, 0x89, 0x96, 0xd0, 0x6f, 0x61, 0x75, 0xc2, 0xd6, 0x40, 0x20, 0xed, 0x44, + 0xbe, 0xa8, 0xaf, 0x58, 0xaf, 0xb5, 0xad, 0x4c, 0x46, 0x5b, 0xb0, 0x32, 0x71, 0x50, 0xd2, 0xf4, + 0x14, 0x7a, 0xde, 0x85, 0xce, 0x84, 0xbe, 0x4e, 0xa5, 0x7b, 0xa4, 0xd0, 0x01, 0xcc, 0x17, 0xac, + 0x1c, 0xed, 0x1f, 0x5f, 0x7b, 0x76, 0x13, 0x6a, 0xdc, 0x3f, 0xbb, 0x79, 0xa2, 0x92, 0x1a, 0x68, + 0x17, 0x96, 0x0b, 0xf6, 0xf2, 0x27, 0xfb, 0x95, 0xb6, 0xa0, 0x52, 0xa7, 0x93, 0xa7, 0x4e, 0xd9, + 0xbb, 0xb6, 0xa2, 0x3b, 0xff, 0xcb, 0x0f, 0xb0, 0xf3, 0x97, 0x79, 0xe9, 0xe5, 0x7b, 0xe0, 0xa5, + 0x3f, 0xc3, 0x46, 0x6f, 0xf0, 0xf2, 0xbd, 0x14, 0xf6, 0x33, 0x58, 0xec, 0x52, 0x4f, 0x00, 0xdd, + 0xfb, 0x7a, 0xd0, 0x27, 0x3c, 0xa1, 0x8e, 0x48, 0xe4, 0x40, 0xae, 0x64, 0xa0, 0x35, 0x5b, 0x4b, + 0xe8, 0x35, 0xcc, 0x6b, 0xdd, 0xfb, 0x67, 0xd5, 0x2b, 0x68, 0x89, 0xb3, 0x79, 0xc0, 0x9b, 0xa5, + 0xe7, 0xbf, 0x29, 0x81, 0x52, 0x98, 0xdf, 0x17, 0xbd, 0xd7, 0xdc, 0x5b, 0xb6, 0x4c, 0xcf, 0x8f, + 0x46, 0x19, 0x62, 0xca, 0x7d, 0x53, 0xed, 0x49, 0xc8, 0x72, 0x4c, 0x5d, 0xcc, 0xf1, 0x6f, 0x4a, + 0x98, 0xee, 0x8a, 0x9d, 0xb2, 0xc2, 0xb6, 0x66, 0x83, 0x5c, 0x61, 0x1b, 0xfd, 0x49, 0xfc, 0xc3, + 0x2d, 0xb8, 0x2d, 0xc1, 0xfd, 0xfa, 0x3a, 0xb8, 0x0b, 0x39, 0x5c, 0x0e, 0xb8, 0x0c, 0xb9, 0x0d, + 0x8b, 0x1a, 0xbf, 0x77, 0xe4, 0xaf, 0xc9, 0x01, 0x68, 0x34, 0x2b, 0x71, 0xfb, 0xec, 0x7f, 0x01, + 0x00, 0x00, 0xff, 0xff, 0xf2, 0x23, 0xd6, 0xcf, 0xfa, 0x17, 0x00, 0x00, +} diff --git a/api/attribute.proto b/api/attribute.proto new file mode 100644 index 00000000..dea22b4f --- /dev/null +++ b/api/attribute.proto @@ -0,0 +1,504 @@ +// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation files +// (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +syntax = "proto3"; + +import "google/protobuf/any.proto"; + +package gobgpapi; + +message OriginAttribute { + uint32 origin = 1; +} + +message AsSegment { + uint32 type = 1; + repeated uint32 numbers = 2; +} + +message AsPathAttribute { + repeated AsSegment segments = 1; +} + +message NextHopAttribute { + string next_hop = 1; +} + +message MultiExitDiscAttribute { + uint32 med = 1; +} + +message LocalPrefAttribute { + uint32 local_pref = 1; +} + +message AtomicAggregateAttribute { +} + +message AggregatorAttribute { + uint32 as = 2; + string address = 3; +} + +message CommunitiesAttribute { + repeated uint32 communities = 1; +} + +message OriginatorIdAttribute { + string id = 1; +} + +message ClusterListAttribute { + repeated string ids = 1; +} + +// IPAddressPrefix represents the NLRI for: +// - AFI=1, SAFI=1 +// - AFI=2, SAFI=1 +message IPAddressPrefix { + uint32 prefix_len = 1; + string prefix = 2; +} + +// LabeledIPAddressPrefix represents the NLRI for: +// - AFI=1, SAFI=4 +// - AFI=2, SAFI=4 +message LabeledIPAddressPrefix { + repeated uint32 labels = 1; + uint32 prefix_len = 2; + string prefix = 3; +} + +// EncapsulationNLRI represents the NLRI for: +// - AFI=1, SAFI=7 +// - AFI=2, SAFI=7 +message EncapsulationNLRI { + string address = 1; +} + +message RouteDistinguisherTwoOctetAS { + uint32 admin = 1; + uint32 assigned = 2; +} + +message RouteDistinguisherIPAddress { + string admin = 1; + uint32 assigned = 2; +} + +message RouteDistinguisherFourOctetAS { + uint32 admin = 1; + uint32 assigned = 2; +} + +message EthernetSegmentIdentifier { + uint32 type = 1; + bytes value = 2; +} + +// EVPNEthernetAutoDiscoveryRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=1 +message EVPNEthernetAutoDiscoveryRoute { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + google.protobuf.Any rd = 1; + EthernetSegmentIdentifier esi = 2; + uint32 ethernet_tag = 3; + uint32 label = 4; +} + +// EVPNMACIPAdvertisementRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=2 +message EVPNMACIPAdvertisementRoute { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + google.protobuf.Any rd = 1; + EthernetSegmentIdentifier esi = 2; + uint32 ethernet_tag = 3; + string mac_address = 4; + string ip_address = 5; + repeated uint32 labels = 6; +} + +// EVPNInclusiveMulticastEthernetTagRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=3 +message EVPNInclusiveMulticastEthernetTagRoute { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + google.protobuf.Any rd = 1; + uint32 ethernet_tag = 2; + string ip_address = 3; +} + +// EVPNEthernetSegmentRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=4 +message EVPNEthernetSegmentRoute { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + google.protobuf.Any rd = 1; + EthernetSegmentIdentifier esi = 2; + string ip_address = 3; +} + +// EVPNIPPrefixRoute represents the NLRI for: +// - AFI=25, SAFI=70, RouteType=5 +message EVPNIPPrefixRoute { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + google.protobuf.Any rd = 1; + EthernetSegmentIdentifier esi = 2; + uint32 ethernet_tag = 3; + string ip_prefix = 4; + uint32 ip_prefix_len = 5; + string gw_address = 6; + uint32 label = 7; +} + +// LabeledVPNIPAddressPrefix represents the NLRI for: +// - AFI=1, SAFI=128 +// - AFI=2, SAFI=128 +message LabeledVPNIPAddressPrefix { + repeated uint32 labels = 1; + // One of: + // - TwoOctetAsSpecificExtended + // - IPv4AddressSpecificExtended + // - FourOctetAsSpecificExtended + google.protobuf.Any rd = 2; + uint32 prefix_len = 3; + string prefix = 4; +} + +// RouteTargetMembershipNLRI represents the NLRI for: +// - AFI=1, SAFI=132 +message RouteTargetMembershipNLRI { + uint32 as = 1; + // One of: + // - TwoOctetAsSpecificExtended + // - IPv4AddressSpecificExtended + // - FourOctetAsSpecificExtended + google.protobuf.Any rt = 2; +} + +message FlowSpecIPPrefix { + uint32 type = 1; + uint32 prefix_len = 2; + string prefix = 3; + // IPv6 only + uint32 offset = 4; +} + +message FlowSpecMAC { + uint32 type = 1; + string address = 2; +} + +message FlowSpecComponentItem { + // Operator for Numeric type, Operand for Bitmask type + uint32 op = 1; + uint64 value = 2; +} + +message FlowSpecComponent { + uint32 type = 1; + repeated FlowSpecComponentItem items = 2; +} + +// FlowSpecNLRI represents the NLRI for: +// - AFI=1, SAFI=133 +// - AFI=2, SAFI=133 +message FlowSpecNLRI { + // One of: + // - FlowSpecIPPrefix + // - FlowSpecMAC + // - FlowSpecComponent + repeated google.protobuf.Any rules = 1; +} + +// VPNFlowSpecNLRI represents the NLRI for: +// - AFI=1, SAFI=134 +// - AFI=2, SAFI=134 +// - AFI=25, SAFI=134 +message VPNFlowSpecNLRI { + // One of: + // - RouteDistinguisherTwoOctetAS + // - RouteDistinguisherIPAddressAS + // - RouteDistinguisherFourOctetAS + google.protobuf.Any rd = 1; + // One of: + // - FlowSpecIPPrefix + // - FlowSpecMAC + // - FlowSpecComponent + repeated google.protobuf.Any rules = 2; +} + +// OpaqueNLRI represents the NLRI for: +// - AFI=16397, SAFI=241 +message OpaqueNLRI { + bytes key = 1; + bytes value = 2; +} + +message MpReachNLRIAttribute { + uint32 family = 1; + repeated string next_hops = 2; + // Each NLRI must be one of: + // - IPAddressPrefix + // - LabeledIPAddressPrefix + // - EncapsulationNLRI + // - EVPNEthernetAutoDiscoveryRoute + // - EVPNMACIPAdvertisementRoute + // - EVPNInclusiveMulticastEthernetTagRoute + // - EVPNEthernetSegmentRoute + // - EVPNIPPrefixRoute + // - LabeledVPNIPAddressPrefix + // - RouteTargetMembershipNLRI + // - FlowSpecNLRI + // - VPNFlowSpecNLRI + // - OpaqueNLRI + repeated google.protobuf.Any nlris = 3; +} + +message MpUnreachNLRIAttribute { + uint32 family = 1; + // The same as NLRI field of MpReachNLRIAttribute + repeated google.protobuf.Any nlris = 3; +} + +message TwoOctetAsSpecificExtended { + bool is_transitive = 1; + uint32 sub_type = 2; + uint32 as = 3; + uint32 local_admin = 4; +} + +message IPv4AddressSpecificExtended { + bool is_transitive = 1; + uint32 sub_type = 2; + string address = 3; + uint32 local_admin = 4; +} + +message FourOctetAsSpecificExtended { + bool is_transitive = 1; + uint32 sub_type = 2; + uint32 as = 3; + uint32 local_admin = 4; +} + +message ValidationExtended { + uint32 state = 1; +} + +message ColorExtended { + uint32 color = 1; +} + +message EncapExtended { + uint32 tunnel_type = 1; +} + +message DefaultGatewayExtended { +} + +message OpaqueExtended { + bool is_transitive = 1; + bytes value = 3; +} + +message ESILabelExtended { + bool is_single_active = 1; + uint32 label = 2; +} + +message ESImportRouteTarget { + string es_import = 1; +} + +message MacMobilityExtended { + bool is_sticky = 1; + uint32 sequence_num = 2; +} + +message RouterMacExtended { + string mac = 1; +} + +message TrafficRateExtended { + uint32 as = 1; + float rate = 2; +} + +message TrafficActionExtended { + bool terminal = 1; + bool sample = 2; +} + +message RedirectTwoOctetAsSpecificExtended { + uint32 as = 1; + uint32 local_admin = 2; +} + +message RedirectIPv4AddressSpecificExtended { + string address = 1; + uint32 local_admin = 2; +} + +message RedirectFourOctetAsSpecificExtended { + uint32 as = 1; + uint32 local_admin = 2; +} + +message TrafficRemarkExtended { + uint32 dscp = 1; +} + +message UnknownExtended { + uint32 type = 1; + bytes value = 2; +} + +message ExtendedCommunitiesAttribute { + // Each Community must be one of: + // - TwoOctetAsSpecificExtended + // - IPv4AddressSpecificExtended + // - FourOctetAsSpecificExtended + // - OpaqueExtended + // - ESILabelExtended + // - MacMobilityExtended + // - RouterMacExtended + // - TrafficRateExtended + // - TrafficActionExtended + // - RedirectTwoOctetAsSpecificExtended + // - RedirectIPv4AddressSpecificExtended + // - RedirectFourOctetAsSpecificExtended + // - TrafficRemarkExtended + // - UnknownExtended + repeated google.protobuf.Any communities = 1; +} + +message As4PathAttribute { + repeated AsSegment segments = 1; +} + +message As4AggregatorAttribute { + uint32 as = 2; + string address = 3; +} + +message PmsiTunnelAttribute { + uint32 flags = 1; + uint32 type = 2; + uint32 label = 3; + bytes id = 4; +} + +message TunnelEncapSubTLVEncapsulation { + uint32 key = 1; + bytes cookie = 2; +} + +message TunnelEncapSubTLVProtocol { + uint32 protocol = 1; +} + +message TunnelEncapSubTLVColor { + uint32 color = 1; +} + +message TunnelEncapSubTLVUnknown { + uint32 type = 1; + bytes value = 2; +} + +message TunnelEncapTLV { + uint32 type = 1; + // Each TLV must be one of: + // - TunnelEncapSubTLVEncapsulation + // - TunnelEncapSubTLVProtocol + // - TunnelEncapSubTLVColor + // - TunnelEncapSubTLVUnknown + repeated google.protobuf.Any tlvs = 2; +} + +message TunnelEncapAttribute { + repeated TunnelEncapTLV tlvs = 1; +} + +message IPv6AddressSpecificExtended { + bool is_transitive = 1; + uint32 sub_type = 2; + string address = 3; + uint32 local_admin = 4; +} + +message RedirectIPv6AddressSpecificExtended { + string address = 1; + uint32 local_admin = 2; +} + +message IP6ExtendedCommunitiesAttribute { + // Each Community must be one of: + // - IPv6AddressSpecificExtended + // - RedirectIPv6AddressSpecificExtended + repeated google.protobuf.Any communities = 1; +} + +message AigpTLVIGPMetric { + uint64 metric = 1; +} + +message AigpTLVUnknown { + uint32 type = 1; + bytes value = 2; +} + +message AigpAttribute { + // Each TLV must be one of: + // - AigpTLVIGPMetric + // - AigpTLVUnknown + repeated google.protobuf.Any tlvs = 1; +} + +message LargeCommunity { + uint32 global_admin = 1; + uint32 local_data1 = 2; + uint32 local_data2 = 3; +} + +message LargeCommunitiesAttribute { + repeated LargeCommunity communities = 1; +} + +message UnknownAttribute { + uint32 flags = 1; + uint32 type = 2; + bytes value = 3; +} diff --git a/api/attribute_test.go b/api/attribute_test.go new file mode 100644 index 00000000..271b0191 --- /dev/null +++ b/api/attribute_test.go @@ -0,0 +1,1416 @@ +// Copyright (C) 2016 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 ( + "net" + "testing" + + "github.com/osrg/gobgp/packet/bgp" + + "github.com/golang/protobuf/ptypes" + "github.com/golang/protobuf/ptypes/any" + "github.com/stretchr/testify/assert" +) + +func Test_OriginAttribute(t *testing.T) { + assert := assert.New(t) + + input := &OriginAttribute{ + Origin: 0, // IGP + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewOriginAttributeFromNative(n) + assert.Equal(input.Origin, output.Origin) +} + +func Test_AsPathAttribute(t *testing.T) { + assert := assert.New(t) + + input := &AsPathAttribute{ + Segments: []*AsSegment{ + { + Type: 1, // SET + Numbers: []uint32{100, 200}, + }, + { + Type: 2, // SEQ + Numbers: []uint32{300, 400}, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewAsPathAttributeFromNative(n) + assert.Equal(2, len(output.Segments)) + assert.Equal(input.Segments, output.Segments) +} + +func Test_NextHopAttribute(t *testing.T) { + assert := assert.New(t) + + input := &NextHopAttribute{ + NextHop: "192.168.0.1", + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewNextHopAttributeFromNative(n) + assert.Equal(input.NextHop, output.NextHop) +} + +func Test_MultiExitDiscAttribute(t *testing.T) { + assert := assert.New(t) + + input := &MultiExitDiscAttribute{ + Med: 100, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMultiExitDiscAttributeFromNative(n) + assert.Equal(input.Med, output.Med) +} + +func Test_LocalPrefAttribute(t *testing.T) { + assert := assert.New(t) + + input := &LocalPrefAttribute{ + LocalPref: 100, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewLocalPrefAttributeFromNative(n) + assert.Equal(input.LocalPref, output.LocalPref) +} + +func Test_AtomicAggregateAttribute(t *testing.T) { + assert := assert.New(t) + + input := &AtomicAggregateAttribute{} + + n, err := input.ToNative() + assert.Nil(err) + + output := NewAtomicAggregateAttributeFromNative(n) + // AtomicAggregateAttribute has no value + assert.NotNil(output) +} + +func Test_AggregatorAttribute(t *testing.T) { + assert := assert.New(t) + + input := &AggregatorAttribute{ + As: 65000, + Address: "1.1.1.1", + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewAggregatorAttributeFromNative(n) + assert.Equal(input.As, output.As) + assert.Equal(input.Address, output.Address) +} + +func Test_CommunitiesAttribute(t *testing.T) { + assert := assert.New(t) + + input := &CommunitiesAttribute{ + Communities: []uint32{100, 200}, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewCommunitiesAttributeFromNative(n) + assert.Equal(input.Communities, output.Communities) +} + +func Test_OriginatorIdAttribute(t *testing.T) { + assert := assert.New(t) + + input := &OriginatorIdAttribute{ + Id: "1.1.1.1", + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewOriginatorIdAttributeFromNative(n) + assert.Equal(input.Id, output.Id) +} + +func Test_ClusterListAttribute(t *testing.T) { + assert := assert.New(t) + + input := &ClusterListAttribute{ + Ids: []string{"1.1.1.1", "2.2.2.2"}, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewClusterListAttributeFromNative(n) + assert.Equal(input.Ids, output.Ids) +} + +func Test_MpReachNLRIAttribute_IPv4_UC(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&IPAddressPrefix{ + PrefixLen: 24, + Prefix: "192.168.101.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&IPAddressPrefix{ + PrefixLen: 24, + Prefix: "192.168.201.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv4_UC), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv6_UC(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&IPAddressPrefix{ + PrefixLen: 64, + Prefix: "2001:db8:1::", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&IPAddressPrefix{ + PrefixLen: 64, + Prefix: "2001:db8:2::", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv6_UC), + NextHops: []string{"2001:db8::1", "2001:db8::2"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv4_MPLS(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&LabeledIPAddressPrefix{ + Labels: []uint32{100}, + PrefixLen: 24, + Prefix: "192.168.101.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&LabeledIPAddressPrefix{ + Labels: []uint32{200}, + PrefixLen: 24, + Prefix: "192.168.201.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv4_MPLS), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv6_MPLS(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&LabeledIPAddressPrefix{ + Labels: []uint32{100}, + PrefixLen: 64, + Prefix: "2001:db8:1::", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&LabeledIPAddressPrefix{ + Labels: []uint32{200}, + PrefixLen: 64, + Prefix: "2001:db8:2::", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv6_MPLS), + NextHops: []string{"2001:db8::1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv4_ENCAP(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&EncapsulationNLRI{ + Address: "192.168.101.1", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&EncapsulationNLRI{ + Address: "192.168.201.1", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv4_ENCAP), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv6_ENCAP(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&EncapsulationNLRI{ + Address: "2001:db8:1::1", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&EncapsulationNLRI{ + Address: "2001:db8:2::1", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv6_ENCAP), + NextHops: []string{"2001:db8::1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_EVPN_AD_Route(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rd, err := ptypes.MarshalAny(&RouteDistinguisherTwoOctetAS{ + Admin: 65000, + Assigned: 100, + }) + assert.Nil(err) + esi := &EthernetSegmentIdentifier{ + Type: 0, + Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + } + a, err := ptypes.MarshalAny(&EVPNEthernetAutoDiscoveryRoute{ + Rd: rd, + Esi: esi, + EthernetTag: 100, + Label: 200, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_EVPN), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +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{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + esi := &EthernetSegmentIdentifier{ + Type: 0, + Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + } + a, err := ptypes.MarshalAny(&EVPNMACIPAdvertisementRoute{ + Rd: rd, + Esi: esi, + EthernetTag: 100, + MacAddress: "aa:bb:cc:dd:ee:ff", + IpAddress: "192.168.101.1", + Labels: []uint32{200}, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_EVPN), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_EVPN_MC_Route(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rd, err := ptypes.MarshalAny(&RouteDistinguisherFourOctetAS{ + Admin: 65000, + Assigned: 100, + }) + assert.Nil(err) + a, err := ptypes.MarshalAny(&EVPNInclusiveMulticastEthernetTagRoute{ + Rd: rd, + EthernetTag: 100, + IpAddress: "192.168.101.1", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_EVPN), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_EVPN_ES_Route(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + esi := &EthernetSegmentIdentifier{ + Type: 0, + Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + } + a, err := ptypes.MarshalAny(&EVPNEthernetSegmentRoute{ + Rd: rd, + Esi: esi, + IpAddress: "192.168.101.1", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_EVPN), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_EVPN_Prefix_Route(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + esi := &EthernetSegmentIdentifier{ + Type: 0, + Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + } + a, err := ptypes.MarshalAny(&EVPNIPPrefixRoute{ + Rd: rd, + Esi: esi, + EthernetTag: 100, + IpPrefixLen: 24, + IpPrefix: "192.168.101.0", + Label: 200, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_EVPN), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv4_VPN(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + a, err := ptypes.MarshalAny(&LabeledVPNIPAddressPrefix{ + Labels: []uint32{100, 200}, + Rd: rd, + PrefixLen: 24, + Prefix: "192.168.101.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv4_VPN), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_IPv6_VPN(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + a, err := ptypes.MarshalAny(&LabeledVPNIPAddressPrefix{ + Labels: []uint32{100, 200}, + Rd: rd, + PrefixLen: 64, + Prefix: "2001:db8:1::", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_IPv6_VPN), + NextHops: []string{"2001:db8::1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_RTC_UC(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 1) + rt, err := ptypes.MarshalAny(&IPv4AddressSpecificExtended{ + IsTransitive: true, + SubType: 0x02, // Route Target + Address: "1.1.1.1", + LocalAdmin: 100, + }) + assert.Nil(err) + a, err := ptypes.MarshalAny(&RouteTargetMembershipNLRI{ + As: 65000, + Rt: rt, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_RTC_UC), + NextHops: []string{"192.168.1.1"}, + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_FS_IPv4_UC(t *testing.T) { + assert := assert.New(t) + + rules := make([]*any.Any, 0, 3) + rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 1, // Destination Prefix + PrefixLen: 24, + Prefix: "192.168.101.0", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 2, // Source Prefix + PrefixLen: 24, + Prefix: "192.168.201.0", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + Type: 3, // IP Protocol + Items: []*FlowSpecComponentItem{ + { + Op: 0x80 | 0x01, // End, EQ + Value: 6, // TCP + }, + }, + }) + assert.Nil(err) + rules = append(rules, rule) + + nlris := make([]*any.Any, 0, 1) + a, err := ptypes.MarshalAny(&FlowSpecNLRI{ + Rules: rules, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_FS_IPv4_UC), + // NextHops: // No nexthop required + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_FS_IPv4_VPN(t *testing.T) { + assert := assert.New(t) + + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + + rules := make([]*any.Any, 0, 3) + rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 1, // Destination Prefix + PrefixLen: 24, + Prefix: "192.168.101.0", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 2, // Source Prefix + PrefixLen: 24, + Prefix: "192.168.201.0", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + Type: 3, // IP Protocol + Items: []*FlowSpecComponentItem{ + { + Op: 0x80 | 0x01, // End, EQ + Value: 6, // TCP + }, + }, + }) + assert.Nil(err) + rules = append(rules, rule) + + nlris := make([]*any.Any, 0, 1) + a, err := ptypes.MarshalAny(&VPNFlowSpecNLRI{ + Rd: rd, + Rules: rules, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_FS_IPv4_VPN), + // NextHops: // No nexthop required + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_FS_IPv6_UC(t *testing.T) { + assert := assert.New(t) + + rules := make([]*any.Any, 0, 3) + rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 1, // Destination Prefix + PrefixLen: 64, + Prefix: "2001:db8:1::", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 2, // Source Prefix + PrefixLen: 64, + Prefix: "2001:db8:2::", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + Type: 3, // Next Header + Items: []*FlowSpecComponentItem{ + { + Op: 0x80 | 0x01, // End, EQ + Value: 6, // TCP + }, + }, + }) + assert.Nil(err) + rules = append(rules, rule) + + nlris := make([]*any.Any, 0, 1) + a, err := ptypes.MarshalAny(&FlowSpecNLRI{ + Rules: rules, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_FS_IPv6_UC), + // NextHops: // No nexthop required + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_FS_IPv6_VPN(t *testing.T) { + assert := assert.New(t) + + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + + rules := make([]*any.Any, 0, 3) + rule, err := ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 1, // Destination Prefix + PrefixLen: 64, + Prefix: "2001:db8:1::", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecIPPrefix{ + Type: 2, // Source Prefix + PrefixLen: 64, + Prefix: "2001:db8:2::", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + Type: 3, // Next Header + Items: []*FlowSpecComponentItem{ + { + Op: 0x80 | 0x01, // End, EQ + Value: 6, // TCP + }, + }, + }) + assert.Nil(err) + rules = append(rules, rule) + + nlris := make([]*any.Any, 0, 1) + a, err := ptypes.MarshalAny(&VPNFlowSpecNLRI{ + Rd: rd, + Rules: rules, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_FS_IPv6_VPN), + // NextHops: // No nexthop required + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpReachNLRIAttribute_FS_L2_VPN(t *testing.T) { + assert := assert.New(t) + + rd, err := ptypes.MarshalAny(&RouteDistinguisherIPAddress{ + Admin: "1.1.1.1", + Assigned: 100, + }) + assert.Nil(err) + + rules := make([]*any.Any, 0, 3) + rule, err := ptypes.MarshalAny(&FlowSpecMAC{ + Type: 15, // Source MAC + Address: "aa:bb:cc:11:22:33", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecMAC{ + Type: 16, // Destination MAC + Address: "dd:ee:ff:11:22:33", + }) + assert.Nil(err) + rules = append(rules, rule) + rule, err = ptypes.MarshalAny(&FlowSpecComponent{ + Type: 21, // VLAN ID + Items: []*FlowSpecComponentItem{ + { + Op: 0x80 | 0x01, // End, EQ + Value: 100, + }, + }, + }) + assert.Nil(err) + rules = append(rules, rule) + + nlris := make([]*any.Any, 0, 1) + a, err := ptypes.MarshalAny(&VPNFlowSpecNLRI{ + Rd: rd, + Rules: rules, + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpReachNLRIAttribute{ + Family: uint32(bgp.RF_FS_L2_VPN), + // NextHops: // No nexthop required + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpReachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(input.NextHops, output.NextHops) + assert.Equal(1, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_MpUnreachNLRIAttribute_IPv4_UC(t *testing.T) { + assert := assert.New(t) + + nlris := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&IPAddressPrefix{ + PrefixLen: 24, + Prefix: "192.168.101.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + a, err = ptypes.MarshalAny(&IPAddressPrefix{ + PrefixLen: 24, + Prefix: "192.168.201.0", + }) + assert.Nil(err) + nlris = append(nlris, a) + + input := &MpUnreachNLRIAttribute{ + Family: uint32(bgp.RF_IPv4_UC), + Nlris: nlris, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewMpUnreachNLRIAttributeFromNative(n) + assert.Equal(input.Family, output.Family) + assert.Equal(2, len(output.Nlris)) + for idx, inputNLRI := range input.Nlris { + outputNLRI := output.Nlris[idx] + assert.Equal(inputNLRI.TypeUrl, outputNLRI.TypeUrl) + assert.Equal(inputNLRI.Value, outputNLRI.Value) + } +} + +func Test_ExtendedCommunitiesAttribute(t *testing.T) { + assert := assert.New(t) + + communities := make([]*any.Any, 0, 19) + a, err := ptypes.MarshalAny(&TwoOctetAsSpecificExtended{ + IsTransitive: true, + SubType: 0x02, // ROUTE_TARGET + As: 65001, + LocalAdmin: 100, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&IPv4AddressSpecificExtended{ + IsTransitive: true, + SubType: 0x02, // ROUTE_TARGET + Address: "2.2.2.2", + LocalAdmin: 200, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&FourOctetAsSpecificExtended{ + IsTransitive: true, + SubType: 0x02, // ROUTE_TARGET + As: 65003, + LocalAdmin: 300, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&ValidationExtended{ + State: 0, // VALID + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&ColorExtended{ + Color: 400, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&EncapExtended{ + TunnelType: 8, // VXLAN + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&DefaultGatewayExtended{ + // No value + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&OpaqueExtended{ + IsTransitive: true, + Value: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&ESILabelExtended{ + IsSingleActive: true, + Label: 500, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&ESImportRouteTarget{ + EsImport: "aa:bb:cc:dd:ee:ff", + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&MacMobilityExtended{ + IsSticky: true, + SequenceNum: 1, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&RouterMacExtended{ + Mac: "ff:ee:dd:cc:bb:aa", + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&TrafficRateExtended{ + As: 65004, + Rate: 100.0, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&TrafficActionExtended{ + Terminal: true, + Sample: false, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&RedirectTwoOctetAsSpecificExtended{ + As: 65005, + LocalAdmin: 500, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&RedirectIPv4AddressSpecificExtended{ + Address: "6.6.6.6", + LocalAdmin: 600, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&RedirectFourOctetAsSpecificExtended{ + As: 65007, + LocalAdmin: 700, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&TrafficRemarkExtended{ + Dscp: 0x0a, // AF11 + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&UnknownExtended{ + Type: 0xff, // Max of uint8 + Value: []byte{1, 2, 3, 4, 5, 6, 7}, + }) + assert.Nil(err) + communities = append(communities, a) + + input := &ExtendedCommunitiesAttribute{ + Communities: communities, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewExtendedCommunitiesAttributeFromNative(n) + assert.Equal(19, len(output.Communities)) + for idx, inputCommunity := range input.Communities { + outputCommunity := output.Communities[idx] + assert.Equal(inputCommunity.TypeUrl, outputCommunity.TypeUrl) + assert.Equal(inputCommunity.Value, outputCommunity.Value) + } +} + +func Test_As4PathAttribute(t *testing.T) { + assert := assert.New(t) + + input := &As4PathAttribute{ + Segments: []*AsSegment{ + { + Type: 1, // SET + Numbers: []uint32{100, 200}, + }, + { + Type: 2, // SEQ + Numbers: []uint32{300, 400}, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewAs4PathAttributeFromNative(n) + assert.Equal(2, len(output.Segments)) + assert.Equal(input.Segments, output.Segments) +} + +func Test_As4AggregatorAttribute(t *testing.T) { + assert := assert.New(t) + + input := &As4AggregatorAttribute{ + As: 65000, + Address: "1.1.1.1", + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewAs4AggregatorAttributeFromNative(n) + assert.Equal(input.As, output.As) + assert.Equal(input.Address, output.Address) +} + +func Test_PmsiTunnelAttribute(t *testing.T) { + assert := assert.New(t) + + input := &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() + assert.Nil(err) + + output := NewPmsiTunnelAttributeFromNative(n) + assert.Equal(input.Flags, output.Flags) + assert.Equal(input.Type, output.Type) + assert.Equal(input.Label, output.Label) + assert.Equal(input.Id, output.Id) +} + +func Test_TunnelEncapAttribute(t *testing.T) { + assert := assert.New(t) + + subTlvs := make([]*any.Any, 0, 4) + a, err := ptypes.MarshalAny(&TunnelEncapSubTLVEncapsulation{ + Key: 100, + Cookie: []byte{0x11, 0x22, 0x33, 0x44}, + }) + assert.Nil(err) + subTlvs = append(subTlvs, a) + a, err = ptypes.MarshalAny(&TunnelEncapSubTLVProtocol{ + Protocol: 200, + }) + assert.Nil(err) + subTlvs = append(subTlvs, a) + a, err = ptypes.MarshalAny(&TunnelEncapSubTLVColor{ + Color: 300, + }) + assert.Nil(err) + subTlvs = append(subTlvs, a) + a, err = ptypes.MarshalAny(&TunnelEncapSubTLVUnknown{ + Type: 0xff, // Max of uint8 + Value: []byte{0x55, 0x66, 0x77, 0x88}, + }) + assert.Nil(err) + subTlvs = append(subTlvs, a) + + input := &TunnelEncapAttribute{ + Tlvs: []*TunnelEncapTLV{ + { + Type: 8, // VXLAN + Tlvs: subTlvs, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewTunnelEncapAttributeFromNative(n) + 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)) + for idx, inputSubTlv := range input.Tlvs[0].Tlvs { + outputSubTlv := output.Tlvs[0].Tlvs[idx] + assert.Equal(inputSubTlv.TypeUrl, outputSubTlv.TypeUrl) + assert.Equal(inputSubTlv.Value, outputSubTlv.Value) + } +} + +func Test_IP6ExtendedCommunitiesAttribute(t *testing.T) { + assert := assert.New(t) + + communities := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&IPv6AddressSpecificExtended{ + IsTransitive: true, + SubType: 0xff, // Max of uint8 + Address: "2001:db8:1::1", + LocalAdmin: 100, + }) + assert.Nil(err) + communities = append(communities, a) + a, err = ptypes.MarshalAny(&RedirectIPv6AddressSpecificExtended{ + Address: "2001:db8:2::1", + LocalAdmin: 200, + }) + assert.Nil(err) + communities = append(communities, a) + + input := &IP6ExtendedCommunitiesAttribute{ + Communities: communities, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewIP6ExtendedCommunitiesAttributeFromNative(n) + assert.Equal(2, len(output.Communities)) + for idx, inputCommunity := range input.Communities { + outputCommunity := output.Communities[idx] + assert.Equal(inputCommunity.TypeUrl, outputCommunity.TypeUrl) + assert.Equal(inputCommunity.Value, outputCommunity.Value) + } +} + +func Test_AigpAttribute(t *testing.T) { + assert := assert.New(t) + + tlvs := make([]*any.Any, 0, 2) + a, err := ptypes.MarshalAny(&AigpTLVIGPMetric{ + Metric: 50, + }) + assert.Nil(err) + tlvs = append(tlvs, a) + a, err = ptypes.MarshalAny(&AigpTLVUnknown{ + Type: 0xff, // Max of uint8 + Value: []byte{0x11, 0x22, 0x33, 0x44}, + }) + assert.Nil(err) + tlvs = append(tlvs, a) + + input := &AigpAttribute{ + Tlvs: tlvs, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewAigpAttributeFromNative(n) + assert.Equal(2, len(output.Tlvs)) + for idx, inputTlv := range input.Tlvs { + outputTlv := output.Tlvs[idx] + assert.Equal(inputTlv.TypeUrl, outputTlv.TypeUrl) + assert.Equal(inputTlv.Value, outputTlv.Value) + } +} + +func Test_LargeCommunitiesAttribute(t *testing.T) { + assert := assert.New(t) + + input := &LargeCommunitiesAttribute{ + Communities: []*LargeCommunity{ + { + GlobalAdmin: 65001, + LocalData1: 100, + LocalData2: 200, + }, + { + GlobalAdmin: 65002, + LocalData1: 300, + LocalData2: 400, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewLargeCommunitiesAttributeFromNative(n) + assert.Equal(2, len(output.Communities)) + assert.Equal(input.Communities, output.Communities) +} + +func Test_UnknownAttribute(t *testing.T) { + assert := assert.New(t) + + input := &UnknownAttribute{ + Flags: (1 << 6) | (1 << 7), // OPTIONAL and TRANSITIVE + Type: 0xff, + Value: []byte{0x11, 0x22, 0x33, 0x44}, + } + + n, err := input.ToNative() + assert.Nil(err) + + output := NewUnknownAttributeFromNative(n) + assert.Equal(input.Flags, output.Flags) + assert.Equal(input.Type, output.Type) + assert.Equal(input.Value, output.Value) +} diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index b6364c31..622d76ed 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -6,6 +6,7 @@ Package gobgpapi is a generated protocol buffer package. It is generated from these files: gobgp.proto + attribute.proto It has these top-level messages: GetNeighborRequest @@ -180,6 +181,78 @@ It has these top-level messages: TableInfo GetRibInfoRequest GetRibInfoResponse + OriginAttribute + AsSegment + AsPathAttribute + NextHopAttribute + MultiExitDiscAttribute + LocalPrefAttribute + AtomicAggregateAttribute + AggregatorAttribute + CommunitiesAttribute + OriginatorIdAttribute + ClusterListAttribute + IPAddressPrefix + LabeledIPAddressPrefix + EncapsulationNLRI + RouteDistinguisherTwoOctetAS + RouteDistinguisherIPAddress + RouteDistinguisherFourOctetAS + EthernetSegmentIdentifier + EVPNEthernetAutoDiscoveryRoute + EVPNMACIPAdvertisementRoute + EVPNInclusiveMulticastEthernetTagRoute + EVPNEthernetSegmentRoute + EVPNIPPrefixRoute + LabeledVPNIPAddressPrefix + RouteTargetMembershipNLRI + FlowSpecIPPrefix + FlowSpecMAC + FlowSpecComponentItem + FlowSpecComponent + FlowSpecNLRI + VPNFlowSpecNLRI + OpaqueNLRI + MpReachNLRIAttribute + MpUnreachNLRIAttribute + TwoOctetAsSpecificExtended + IPv4AddressSpecificExtended + FourOctetAsSpecificExtended + ValidationExtended + ColorExtended + EncapExtended + DefaultGatewayExtended + OpaqueExtended + ESILabelExtended + ESImportRouteTarget + MacMobilityExtended + RouterMacExtended + TrafficRateExtended + TrafficActionExtended + RedirectTwoOctetAsSpecificExtended + RedirectIPv4AddressSpecificExtended + RedirectFourOctetAsSpecificExtended + TrafficRemarkExtended + UnknownExtended + ExtendedCommunitiesAttribute + As4PathAttribute + As4AggregatorAttribute + PmsiTunnelAttribute + TunnelEncapSubTLVEncapsulation + TunnelEncapSubTLVProtocol + TunnelEncapSubTLVColor + TunnelEncapSubTLVUnknown + TunnelEncapTLV + TunnelEncapAttribute + IPv6AddressSpecificExtended + RedirectIPv6AddressSpecificExtended + IP6ExtendedCommunitiesAttribute + AigpTLVIGPMetric + AigpTLVUnknown + AigpAttribute + LargeCommunity + LargeCommunitiesAttribute + UnknownAttribute */ package gobgpapi diff --git a/tools/spell-check/ignore.txt b/tools/spell-check/ignore.txt index 4163d941..4ad36108 100644 --- a/tools/spell-check/ignore.txt +++ b/tools/spell-check/ignore.txt @@ -15,6 +15,8 @@ itoa setsockopt Sprintf strconv +Unmarshal +unmarshal # Implementation specific dumpv2 |