update gobgp pkg
This commit is contained in:
343
vendor/github.com/osrg/gobgp/internal/pkg/apiutil/attribute.go
generated
vendored
343
vendor/github.com/osrg/gobgp/internal/pkg/apiutil/attribute.go
generated
vendored
@@ -634,28 +634,54 @@ func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any {
|
||||
switch n := v.NLRI.(type) {
|
||||
case *bgp.LsNodeNLRI:
|
||||
nlri = &api.LsAddrPrefix{
|
||||
Type: api.LsNLRIType_LS_NLRI_NODE,
|
||||
Nlri: MarshalLsNodeNLRI(n),
|
||||
Type: api.LsNLRIType_LS_NLRI_NODE,
|
||||
Nlri: MarshalLsNodeNLRI(n),
|
||||
Length: uint32(n.Length),
|
||||
ProtocolId: api.LsProtocolID(n.ProtocolID),
|
||||
Identifier: n.Identifier,
|
||||
}
|
||||
|
||||
case *bgp.LsLinkNLRI:
|
||||
nlri = &api.LsAddrPrefix{
|
||||
Type: api.LsNLRIType_LS_NLRI_LINK,
|
||||
Nlri: MarshalLsLinkNLRI(n),
|
||||
Type: api.LsNLRIType_LS_NLRI_LINK,
|
||||
Nlri: MarshalLsLinkNLRI(n),
|
||||
Length: uint32(n.Length),
|
||||
ProtocolId: api.LsProtocolID(n.ProtocolID),
|
||||
Identifier: n.Identifier,
|
||||
}
|
||||
|
||||
case *bgp.LsPrefixV4NLRI:
|
||||
nlri = &api.LsAddrPrefix{
|
||||
Type: api.LsNLRIType_LS_NLRI_PREFIX_V4,
|
||||
Nlri: MarshalLsPrefixV4NLRI(n),
|
||||
Type: api.LsNLRIType_LS_NLRI_PREFIX_V4,
|
||||
Nlri: MarshalLsPrefixV4NLRI(n),
|
||||
Length: uint32(n.Length),
|
||||
ProtocolId: api.LsProtocolID(n.ProtocolID),
|
||||
Identifier: n.Identifier,
|
||||
}
|
||||
|
||||
case *bgp.LsPrefixV6NLRI:
|
||||
nlri = &api.LsAddrPrefix{
|
||||
Type: api.LsNLRIType_LS_NLRI_PREFIX_V6,
|
||||
Nlri: MarshalLsPrefixV6NLRI(n),
|
||||
Type: api.LsNLRIType_LS_NLRI_PREFIX_V6,
|
||||
Nlri: MarshalLsPrefixV6NLRI(n),
|
||||
Length: uint32(n.Length),
|
||||
ProtocolId: api.LsProtocolID(n.ProtocolID),
|
||||
Identifier: n.Identifier,
|
||||
}
|
||||
}
|
||||
case *bgp.SRPolicyIPv4:
|
||||
nlri = &api.SRPolicyNLRI{
|
||||
Length: uint32(v.Length),
|
||||
Distinguisher: v.Distinguisher,
|
||||
Color: v.Color,
|
||||
Endpoint: v.Endpoint,
|
||||
}
|
||||
case *bgp.SRPolicyIPv6:
|
||||
nlri = &api.SRPolicyNLRI{
|
||||
Length: uint32(v.Length),
|
||||
Distinguisher: v.Distinguisher,
|
||||
Color: v.Color,
|
||||
Endpoint: v.Endpoint,
|
||||
}
|
||||
}
|
||||
|
||||
an, _ := ptypes.MarshalAny(nlri)
|
||||
@@ -756,6 +782,13 @@ func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, er
|
||||
}
|
||||
nlri = bgp.NewEVPNIPPrefixRoute(rd, *esi, v.EthernetTag, uint8(v.IpPrefixLen), v.IpPrefix, v.GwAddress, v.Label)
|
||||
}
|
||||
case *api.SRPolicyNLRI:
|
||||
switch rf {
|
||||
case bgp.RF_SR_POLICY_IPv4:
|
||||
nlri = bgp.NewSRPolicyIPv4(v.Length, v.Distinguisher, v.Color, v.Endpoint)
|
||||
case bgp.RF_SR_POLICY_IPv6:
|
||||
nlri = bgp.NewSRPolicyIPv6(v.Length, v.Distinguisher, v.Color, v.Endpoint)
|
||||
}
|
||||
case *api.LabeledVPNIPAddressPrefix:
|
||||
rd, err := UnmarshalRD(v.Rd)
|
||||
if err != nil {
|
||||
@@ -828,7 +861,7 @@ func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *api.MpR
|
||||
nexthops = nil
|
||||
} else {
|
||||
nexthops = []string{a.Nexthop.String()}
|
||||
if a.LinkLocalNexthop != nil {
|
||||
if a.LinkLocalNexthop != nil && a.LinkLocalNexthop.IsLinkLocalUnicast() {
|
||||
nexthops = append(nexthops, a.LinkLocalNexthop.String())
|
||||
}
|
||||
}
|
||||
@@ -951,6 +984,11 @@ func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommu
|
||||
community = &api.ValidationExtended{
|
||||
State: uint32(v.State),
|
||||
}
|
||||
case *bgp.LinkBandwidthExtended:
|
||||
community = &api.LinkBandiwdthExtended{
|
||||
As: uint32(v.AS),
|
||||
Bandwidth: v.Bandwidth,
|
||||
}
|
||||
case *bgp.ColorExtended:
|
||||
community = &api.ColorExtended{
|
||||
Color: v.Color,
|
||||
@@ -1050,6 +1088,8 @@ func unmarshalExComm(a *api.ExtendedCommunitiesAttribute) (*bgp.PathAttributeExt
|
||||
community = bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive)
|
||||
case *api.ValidationExtended:
|
||||
community = bgp.NewValidationExtended(bgp.ValidationState(v.State))
|
||||
case *api.LinkBandiwdthExtended:
|
||||
community = bgp.NewLinkBandwidthExtended(uint16(v.As), v.Bandwidth)
|
||||
case *api.ColorExtended:
|
||||
community = bgp.NewColorExtended(v.Color)
|
||||
case *api.EncapExtended:
|
||||
@@ -1143,11 +1183,49 @@ func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *api.Tun
|
||||
subTlv = &api.TunnelEncapSubTLVColor{
|
||||
Color: sv.Color,
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVEgressEndpoint:
|
||||
subTlv = &api.TunnelEncapSubTLVEgressEndpoint{
|
||||
Address: sv.Address.String(),
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVUDPDestPort:
|
||||
subTlv = &api.TunnelEncapSubTLVUDPDestPort{
|
||||
Port: uint32(sv.UDPDestPort),
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVUnknown:
|
||||
subTlv = &api.TunnelEncapSubTLVUnknown{
|
||||
Type: uint32(sv.Type),
|
||||
Value: sv.Value,
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVSRBSID:
|
||||
subTlv = MarshalSRBSID(sv)
|
||||
// TODO (sbezverk) Add processing of SRv6 Binding SID when it gets assigned ID
|
||||
case *bgp.TunnelEncapSubTLVSRCandidatePathName:
|
||||
subTlv = &api.TunnelEncapSubTLVSRCandidatePathName{
|
||||
CandidatePathName: sv.CandidatePathName,
|
||||
}
|
||||
// TODO (sbezverk) Add processing of SR Policy name when it gets assigned ID
|
||||
case *bgp.TunnelEncapSubTLVSRENLP:
|
||||
subTlv = &api.TunnelEncapSubTLVSRENLP{
|
||||
Flags: uint32(sv.Flags),
|
||||
Enlp: api.ENLPType(sv.ENLP),
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVSRPreference:
|
||||
subTlv = &api.TunnelEncapSubTLVSRPreference{
|
||||
Flags: uint32(sv.Flags),
|
||||
Preference: sv.Preference,
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVSRPriority:
|
||||
subTlv = &api.TunnelEncapSubTLVSRPriority{
|
||||
Priority: uint32(sv.Priority),
|
||||
}
|
||||
case *bgp.TunnelEncapSubTLVSRSegmentList:
|
||||
subTlv = &api.TunnelEncapSubTLVSRSegmentList{
|
||||
Weight: &api.SRWeight{
|
||||
Flags: uint32(sv.Weight.Flags),
|
||||
Weight: uint32(sv.Weight.Weight),
|
||||
},
|
||||
Segments: MarshalSRSegments(sv.Segments),
|
||||
}
|
||||
}
|
||||
an, _ := ptypes.MarshalAny(subTlv)
|
||||
subTlvs = append(subTlvs, an)
|
||||
@@ -1433,6 +1511,9 @@ func MarshalPathAttributes(attrList []bgp.PathAttributeInterface) []*any.Any {
|
||||
case *bgp.PathAttributeLs:
|
||||
n, _ := ptypes.MarshalAny(NewLsAttributeFromNative(a))
|
||||
anyList = append(anyList, n)
|
||||
case *bgp.PathAttributePrefixSID:
|
||||
n, _ := ptypes.MarshalAny(NewPrefixSIDAttributeFromNative(a))
|
||||
anyList = append(anyList, n)
|
||||
case *bgp.PathAttributeUnknown:
|
||||
n, _ := ptypes.MarshalAny(NewUnknownAttributeFromNative(a))
|
||||
anyList = append(anyList, n)
|
||||
@@ -1506,6 +1587,9 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
|
||||
}
|
||||
return bgp.NewPathAttributeClusterList(a.Ids), nil
|
||||
case *api.MpReachNLRIAttribute:
|
||||
if a.Family == nil {
|
||||
return nil, fmt.Errorf("empty family")
|
||||
}
|
||||
rf := ToRouteFamily(a.Family)
|
||||
nlris, err := UnmarshalNLRIs(rf, a.Nlris)
|
||||
if err != nil {
|
||||
@@ -1589,10 +1673,62 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
|
||||
subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol))
|
||||
case *api.TunnelEncapSubTLVColor:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color)
|
||||
case *api.TunnelEncapSubTLVEgressEndpoint:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVEgressEndpoint(sv.Address)
|
||||
case *api.TunnelEncapSubTLVUDPDestPort:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVUDPDestPort(uint16(sv.Port))
|
||||
case *api.TunnelEncapSubTLVSRPreference:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVSRPreference(sv.Flags, sv.Preference)
|
||||
case *api.TunnelEncapSubTLVSRPriority:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVSRPriority(uint8(sv.Priority))
|
||||
case *api.TunnelEncapSubTLVSRCandidatePathName:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVSRCandidatePathName(sv.CandidatePathName)
|
||||
case *api.TunnelEncapSubTLVSRENLP:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVSRENLP(sv.Flags, bgp.SRENLPValue(sv.Enlp))
|
||||
case *api.TunnelEncapSubTLVSRBindingSID:
|
||||
var err error
|
||||
subTlv, err = UnmarshalSRBSID(sv.Bsid)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err)
|
||||
}
|
||||
case *api.TunnelEncapSubTLVSRSegmentList:
|
||||
var err error
|
||||
weight := uint32(0)
|
||||
flags := uint8(0)
|
||||
if sv.Weight != nil {
|
||||
weight = sv.Weight.Weight
|
||||
flags = uint8(sv.Weight.Flags)
|
||||
}
|
||||
s := &bgp.TunnelEncapSubTLVSRSegmentList{
|
||||
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
|
||||
Type: bgp.ENCAP_SUBTLV_TYPE_SRSEGMENT_LIST,
|
||||
Length: uint16(6), // Weight (6 bytes) + length of segment (added later, after all segments are discovered)
|
||||
},
|
||||
Weight: &bgp.SegmentListWeight{
|
||||
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
|
||||
Type: bgp.SegmentListSubTLVWeight,
|
||||
Length: uint16(6),
|
||||
},
|
||||
Flags: flags,
|
||||
Weight: weight,
|
||||
},
|
||||
Segments: make([]bgp.TunnelEncapSubTLVInterface, 0),
|
||||
}
|
||||
if len(sv.Segments) != 0 {
|
||||
s.Segments, err = UnmarshalSRSegments(sv.Segments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err)
|
||||
}
|
||||
}
|
||||
// Get total length of Segment List Sub TLV
|
||||
for _, seg := range s.Segments {
|
||||
s.TunnelEncapSubTLV.Length += uint16(seg.Len() + 2) // Adding 1 byte of type and 1 byte of length for each Segment object
|
||||
}
|
||||
subTlv = s
|
||||
case *api.TunnelEncapSubTLVUnknown:
|
||||
subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v", subValue.Message)
|
||||
return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v type: %T", subValue.Message, sv)
|
||||
}
|
||||
subTlvs = append(subTlvs, subTlv)
|
||||
}
|
||||
@@ -1654,3 +1790,190 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
|
||||
}
|
||||
return nil, errors.New("unknown path attribute")
|
||||
}
|
||||
|
||||
// MarshalSRBSID marshals SR Policy Binding SID Sub TLV structure
|
||||
func MarshalSRBSID(bsid *bgp.TunnelEncapSubTLVSRBSID) *any.Any {
|
||||
var r proto.Message
|
||||
s := &api.SRBindingSID{
|
||||
Sid: make([]byte, len(bsid.BSID.Value)),
|
||||
}
|
||||
copy(s.Sid, bsid.BSID.Value)
|
||||
s.SFlag = bsid.Flags&0x80 == 0x80
|
||||
s.IFlag = bsid.Flags&0x40 == 0x40
|
||||
r = s
|
||||
a, _ := ptypes.MarshalAny(r)
|
||||
return a
|
||||
}
|
||||
|
||||
// UnmarshalSRBSID unmarshals SR Policy Binding SID Sub TLV and returns native TunnelEncapSubTLVInterface interface
|
||||
func UnmarshalSRBSID(bsid *any.Any) (bgp.TunnelEncapSubTLVInterface, error) {
|
||||
var value ptypes.DynamicAny
|
||||
if err := ptypes.UnmarshalAny(bsid, &value); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal tunnel encap sub tlv: %s", err)
|
||||
}
|
||||
switch v := value.Message.(type) {
|
||||
case *api.SRBindingSID:
|
||||
b, err := bgp.NewBSID(v.Sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
flags := uint8(0x0)
|
||||
if v.SFlag {
|
||||
flags += 0x80
|
||||
}
|
||||
if v.IFlag {
|
||||
flags += 0x40
|
||||
}
|
||||
return &bgp.TunnelEncapSubTLVSRBSID{
|
||||
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
|
||||
Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID,
|
||||
Length: uint16(2 + b.Len()),
|
||||
},
|
||||
BSID: b,
|
||||
Flags: flags,
|
||||
}, nil
|
||||
case *api.SRv6BindingSID:
|
||||
b, err := bgp.NewBSID(v.Sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &bgp.TunnelEncapSubTLVSRv6BSID{
|
||||
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
|
||||
Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID,
|
||||
Length: uint16(2 + b.Len()),
|
||||
},
|
||||
Flags: 0,
|
||||
BSID: b,
|
||||
}
|
||||
|
||||
if v.EndpointBehaviorStructure != nil {
|
||||
result.EPBAS = &bgp.SRv6EndpointBehaviorStructure{
|
||||
Behavior: bgp.SRBehavior(v.EndpointBehaviorStructure.Behavior),
|
||||
BlockLen: uint8(v.EndpointBehaviorStructure.BlockLen),
|
||||
NodeLen: uint8(v.EndpointBehaviorStructure.NodeLen),
|
||||
FuncLen: uint8(v.EndpointBehaviorStructure.FuncLen),
|
||||
ArgLen: uint8(v.EndpointBehaviorStructure.ArgLen),
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown binding sid type %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalSRSegments marshals a slice of SR Policy Segment List
|
||||
func MarshalSRSegments(segs []bgp.TunnelEncapSubTLVInterface) []*any.Any {
|
||||
anyList := make([]*any.Any, 0, len(segs))
|
||||
for _, seg := range segs {
|
||||
var r proto.Message
|
||||
switch s := seg.(type) {
|
||||
case *bgp.SegmentTypeA:
|
||||
r = &api.SegmentTypeA{
|
||||
Label: s.Label,
|
||||
Flags: &api.SegmentFlags{
|
||||
VFlag: s.Flags&0x80 == 0x80,
|
||||
AFlag: s.Flags&0x40 == 0x40,
|
||||
SFlag: s.Flags&0x20 == 0x20,
|
||||
BFlag: s.Flags&0x10 == 0x10,
|
||||
},
|
||||
}
|
||||
case *bgp.SegmentTypeB:
|
||||
flags := &api.SegmentFlags{
|
||||
VFlag: s.Flags&0x80 == 0x80,
|
||||
AFlag: s.Flags&0x40 == 0x40,
|
||||
SFlag: s.Flags&0x20 == 0x20,
|
||||
BFlag: s.Flags&0x10 == 0x10,
|
||||
}
|
||||
segment := &api.SegmentTypeB{
|
||||
Flags: flags,
|
||||
Sid: s.SID,
|
||||
}
|
||||
if s.SRv6EBS != nil {
|
||||
segment.EndpointBehaviorStructure = &api.SRv6EndPointBehavior{
|
||||
Behavior: api.SRv6Behavior(s.SRv6EBS.Behavior),
|
||||
BlockLen: uint32(s.SRv6EBS.BlockLen),
|
||||
NodeLen: uint32(s.SRv6EBS.NodeLen),
|
||||
FuncLen: uint32(s.SRv6EBS.FuncLen),
|
||||
ArgLen: uint32(s.SRv6EBS.ArgLen),
|
||||
}
|
||||
}
|
||||
r = segment
|
||||
default:
|
||||
// Unrecognize Segment type, skip it
|
||||
continue
|
||||
}
|
||||
a, _ := ptypes.MarshalAny(r)
|
||||
anyList = append(anyList, a)
|
||||
}
|
||||
return anyList
|
||||
}
|
||||
|
||||
// UnmarshalSRSegments unmarshals SR Policy Segments slice of structs
|
||||
func UnmarshalSRSegments(s []*any.Any) ([]bgp.TunnelEncapSubTLVInterface, error) {
|
||||
if len(s) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
segments := make([]bgp.TunnelEncapSubTLVInterface, len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
var value ptypes.DynamicAny
|
||||
if err := ptypes.UnmarshalAny(s[i], &value); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal SR Policy Segment: %s", err)
|
||||
}
|
||||
switch v := value.Message.(type) {
|
||||
case *api.SegmentTypeA:
|
||||
seg := &bgp.SegmentTypeA{
|
||||
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
|
||||
Type: bgp.EncapSubTLVType(bgp.TypeA),
|
||||
Length: 6,
|
||||
},
|
||||
Label: v.Label,
|
||||
}
|
||||
if v.Flags.VFlag {
|
||||
seg.Flags += 0x80
|
||||
}
|
||||
if v.Flags.AFlag {
|
||||
seg.Flags += 0x40
|
||||
}
|
||||
if v.Flags.SFlag {
|
||||
seg.Flags += 0x20
|
||||
}
|
||||
if v.Flags.BFlag {
|
||||
seg.Flags += 0x10
|
||||
}
|
||||
segments[i] = seg
|
||||
case *api.SegmentTypeB:
|
||||
seg := &bgp.SegmentTypeB{
|
||||
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
|
||||
Type: bgp.EncapSubTLVType(bgp.TypeB),
|
||||
Length: 18,
|
||||
},
|
||||
SID: v.GetSid(),
|
||||
}
|
||||
if v.Flags.VFlag {
|
||||
seg.Flags += 0x80
|
||||
}
|
||||
if v.Flags.AFlag {
|
||||
seg.Flags += 0x40
|
||||
}
|
||||
if v.Flags.SFlag {
|
||||
seg.Flags += 0x20
|
||||
}
|
||||
if v.Flags.BFlag {
|
||||
seg.Flags += 0x10
|
||||
}
|
||||
if v.EndpointBehaviorStructure != nil {
|
||||
ebs := v.GetEndpointBehaviorStructure()
|
||||
seg.SRv6EBS = &bgp.SRv6EndpointBehaviorStructure{
|
||||
Behavior: bgp.SRBehavior(ebs.Behavior),
|
||||
BlockLen: uint8(ebs.BlockLen),
|
||||
NodeLen: uint8(ebs.NodeLen),
|
||||
FuncLen: uint8(ebs.FuncLen),
|
||||
ArgLen: uint8(ebs.ArgLen),
|
||||
}
|
||||
}
|
||||
segments[i] = seg
|
||||
}
|
||||
}
|
||||
return segments, nil
|
||||
}
|
||||
|
||||
13
vendor/github.com/osrg/gobgp/internal/pkg/apiutil/capability.go
generated
vendored
13
vendor/github.com/osrg/gobgp/internal/pkg/apiutil/capability.go
generated
vendored
@@ -110,6 +110,15 @@ func NewRouteRefreshCiscoCapability(a *bgp.CapRouteRefreshCisco) *api.RouteRefre
|
||||
return &api.RouteRefreshCiscoCapability{}
|
||||
}
|
||||
|
||||
func NewFQDNCapability(a *bgp.CapFQDN) *api.FQDNCapability {
|
||||
return &api.FQDNCapability{
|
||||
HostNameLen: uint32(a.HostNameLen),
|
||||
HostName: a.HostName,
|
||||
DomainNameLen: uint32(a.DomainNameLen),
|
||||
DomainName: a.DomainName,
|
||||
}
|
||||
}
|
||||
|
||||
func NewUnknownCapability(a *bgp.CapUnknown) *api.UnknownCapability {
|
||||
return &api.UnknownCapability{
|
||||
Code: uint32(a.CapCode),
|
||||
@@ -140,6 +149,8 @@ func MarshalCapability(value bgp.ParameterCapabilityInterface) (*any.Any, error)
|
||||
m = NewLongLivedGracefulRestartCapability(n)
|
||||
case *bgp.CapRouteRefreshCisco:
|
||||
m = NewRouteRefreshCiscoCapability(n)
|
||||
case *bgp.CapFQDN:
|
||||
m = NewFQDNCapability(n)
|
||||
case *bgp.CapUnknown:
|
||||
m = NewUnknownCapability(n)
|
||||
default:
|
||||
@@ -227,6 +238,8 @@ func unmarshalCapability(a *any.Any) (bgp.ParameterCapabilityInterface, error) {
|
||||
return bgp.NewCapLongLivedGracefulRestart(tuples), nil
|
||||
case *api.RouteRefreshCiscoCapability:
|
||||
return bgp.NewCapRouteRefreshCisco(), nil
|
||||
case *api.FQDNCapability:
|
||||
return bgp.NewCapFQDN(a.HostName, a.DomainName), nil
|
||||
case *api.UnknownCapability:
|
||||
return bgp.NewCapUnknown(bgp.BGPCapabilityCode(a.Code), a.Value), nil
|
||||
}
|
||||
|
||||
18
vendor/github.com/osrg/gobgp/internal/pkg/config/bgp_configs.go
generated
vendored
18
vendor/github.com/osrg/gobgp/internal/pkg/config/bgp_configs.go
generated
vendored
@@ -260,6 +260,8 @@ const (
|
||||
AFI_SAFI_TYPE_IPV6_FLOWSPEC AfiSafiType = "ipv6-flowspec"
|
||||
AFI_SAFI_TYPE_L3VPN_IPV6_FLOWSPEC AfiSafiType = "l3vpn-ipv6-flowspec"
|
||||
AFI_SAFI_TYPE_L2VPN_FLOWSPEC AfiSafiType = "l2vpn-flowspec"
|
||||
AFI_SAFI_TYPE_IPV4_SRPOLICY AfiSafiType = "ipv4-srpolicy"
|
||||
AFI_SAFI_TYPE_IPV6_SRPOLICY AfiSafiType = "ipv6-srpolicy"
|
||||
AFI_SAFI_TYPE_OPAQUE AfiSafiType = "opaque"
|
||||
AFI_SAFI_TYPE_LS AfiSafiType = "ls"
|
||||
)
|
||||
@@ -285,8 +287,10 @@ var AfiSafiTypeToIntMap = map[AfiSafiType]int{
|
||||
AFI_SAFI_TYPE_IPV6_FLOWSPEC: 17,
|
||||
AFI_SAFI_TYPE_L3VPN_IPV6_FLOWSPEC: 18,
|
||||
AFI_SAFI_TYPE_L2VPN_FLOWSPEC: 19,
|
||||
AFI_SAFI_TYPE_OPAQUE: 20,
|
||||
AFI_SAFI_TYPE_LS: 21,
|
||||
AFI_SAFI_TYPE_IPV4_SRPOLICY: 20,
|
||||
AFI_SAFI_TYPE_IPV6_SRPOLICY: 21,
|
||||
AFI_SAFI_TYPE_OPAQUE: 22,
|
||||
AFI_SAFI_TYPE_LS: 23,
|
||||
}
|
||||
|
||||
var IntToAfiSafiTypeMap = map[int]AfiSafiType{
|
||||
@@ -310,8 +314,10 @@ var IntToAfiSafiTypeMap = map[int]AfiSafiType{
|
||||
17: AFI_SAFI_TYPE_IPV6_FLOWSPEC,
|
||||
18: AFI_SAFI_TYPE_L3VPN_IPV6_FLOWSPEC,
|
||||
19: AFI_SAFI_TYPE_L2VPN_FLOWSPEC,
|
||||
20: AFI_SAFI_TYPE_OPAQUE,
|
||||
21: AFI_SAFI_TYPE_LS,
|
||||
20: AFI_SAFI_TYPE_IPV4_SRPOLICY,
|
||||
21: AFI_SAFI_TYPE_IPV6_SRPOLICY,
|
||||
22: AFI_SAFI_TYPE_OPAQUE,
|
||||
23: AFI_SAFI_TYPE_LS,
|
||||
}
|
||||
|
||||
func (v AfiSafiType) Validate() error {
|
||||
@@ -1135,7 +1141,7 @@ type ZebraState struct {
|
||||
MplsLabelRangeSize uint32 `mapstructure:"mpls-label-range-size" json:"mpls-label-range-size,omitempty"`
|
||||
// original -> gobgp:software-name
|
||||
// Configure zebra software name.
|
||||
// quagga, frr3, frr4, frr5, frr6, frr7 can be used.
|
||||
// frr4, cumulus, frr6, frr7, frr7.2, and frr7.3 can be used.
|
||||
SoftwareName string `mapstructure:"software-name" json:"software-name,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1165,7 +1171,7 @@ type ZebraConfig struct {
|
||||
MplsLabelRangeSize uint32 `mapstructure:"mpls-label-range-size" json:"mpls-label-range-size,omitempty"`
|
||||
// original -> gobgp:software-name
|
||||
// Configure zebra software name.
|
||||
// quagga, frr3, frr4, frr5, frr6, frr7 can be used.
|
||||
// frr4, cumulus, frr6, frr7, frr7.2, and frr7.3 can be used.
|
||||
SoftwareName string `mapstructure:"software-name" json:"software-name,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
31
vendor/github.com/osrg/gobgp/internal/pkg/config/util.go
generated
vendored
31
vendor/github.com/osrg/gobgp/internal/pkg/config/util.go
generated
vendored
@@ -130,7 +130,7 @@ func (n *Neighbor) IsConfederation(g *Global) bool {
|
||||
}
|
||||
|
||||
func (n *Neighbor) IsEBGPPeer(g *Global) bool {
|
||||
return n.Config.PeerAs != g.Config.As
|
||||
return n.Config.PeerAs != n.Config.LocalAs
|
||||
}
|
||||
|
||||
func (n *Neighbor) CreateRfMap() map[bgp.RouteFamily]bgp.BGPAddPathMode {
|
||||
@@ -299,14 +299,22 @@ func newAfiSafiConfigFromConfigStruct(c *AfiSafi) *api.AfiSafiConfig {
|
||||
}
|
||||
|
||||
func newApplyPolicyFromConfigStruct(c *ApplyPolicy) *api.ApplyPolicy {
|
||||
f := func(t DefaultPolicyType) api.RouteAction {
|
||||
if t == DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
|
||||
return api.RouteAction_ACCEPT
|
||||
} else if t == DEFAULT_POLICY_TYPE_REJECT_ROUTE {
|
||||
return api.RouteAction_REJECT
|
||||
}
|
||||
return api.RouteAction_NONE
|
||||
}
|
||||
applyPolicy := &api.ApplyPolicy{
|
||||
ImportPolicy: &api.PolicyAssignment{
|
||||
Direction: api.PolicyDirection_IMPORT,
|
||||
DefaultAction: api.RouteAction(c.Config.DefaultImportPolicy.ToInt()),
|
||||
DefaultAction: f(c.Config.DefaultImportPolicy),
|
||||
},
|
||||
ExportPolicy: &api.PolicyAssignment{
|
||||
Direction: api.PolicyDirection_EXPORT,
|
||||
DefaultAction: api.RouteAction(c.Config.DefaultExportPolicy.ToInt()),
|
||||
DefaultAction: f(c.Config.DefaultExportPolicy),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -376,6 +384,13 @@ func newMpGracefulRestartFromConfigStruct(c *MpGracefulRestart) *api.MpGracefulR
|
||||
Config: &api.MpGracefulRestartConfig{
|
||||
Enabled: c.Config.Enabled,
|
||||
},
|
||||
State: &api.MpGracefulRestartState{
|
||||
Enabled: c.State.Enabled,
|
||||
Received: c.State.Received,
|
||||
Advertised: c.State.Advertised,
|
||||
EndOfRibReceived: c.State.EndOfRibReceived,
|
||||
EndOfRibSent: c.State.EndOfRibSent,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,6 +519,10 @@ func NewPeerFromConfigStruct(pconf *Neighbor) *api.Peer {
|
||||
Enabled: pconf.EbgpMultihop.Config.Enabled,
|
||||
MultihopTtl: uint32(pconf.EbgpMultihop.Config.MultihopTtl),
|
||||
},
|
||||
TtlSecurity: &api.TtlSecurity{
|
||||
Enabled: pconf.TtlSecurity.Config.Enabled,
|
||||
TtlMin: uint32(pconf.TtlSecurity.Config.TtlMin),
|
||||
},
|
||||
Timers: &api.Timers{
|
||||
Config: &api.TimersConfig{
|
||||
ConnectRetry: uint64(timer.Config.ConnectRetry),
|
||||
@@ -549,6 +568,8 @@ func NewPeerGroupFromConfigStruct(pconf *PeerGroup) *api.PeerGroup {
|
||||
afiSafis := make([]*api.AfiSafi, 0, len(pconf.AfiSafis))
|
||||
for _, f := range pconf.AfiSafis {
|
||||
if afiSafi := newAfiSafiFromConfigStruct(&f); afiSafi != nil {
|
||||
afiSafi.AddPaths.Config.Receive = pconf.AddPaths.Config.Receive
|
||||
afiSafi.AddPaths.Config.SendMax = uint32(pconf.AddPaths.Config.SendMax)
|
||||
afiSafis = append(afiSafis, afiSafi)
|
||||
}
|
||||
}
|
||||
@@ -576,6 +597,10 @@ func NewPeerGroupFromConfigStruct(pconf *PeerGroup) *api.PeerGroup {
|
||||
Enabled: pconf.EbgpMultihop.Config.Enabled,
|
||||
MultihopTtl: uint32(pconf.EbgpMultihop.Config.MultihopTtl),
|
||||
},
|
||||
TtlSecurity: &api.TtlSecurity{
|
||||
Enabled: pconf.TtlSecurity.Config.Enabled,
|
||||
TtlMin: uint32(pconf.TtlSecurity.Config.TtlMin),
|
||||
},
|
||||
Timers: &api.Timers{
|
||||
Config: &api.TimersConfig{
|
||||
ConnectRetry: uint64(timer.Config.ConnectRetry),
|
||||
|
||||
144
vendor/github.com/osrg/gobgp/internal/pkg/table/destination.go
generated
vendored
144
vendor/github.com/osrg/gobgp/internal/pkg/table/destination.go
generated
vendored
@@ -50,6 +50,7 @@ const (
|
||||
BPR_ROUTER_ID
|
||||
BPR_OLDER
|
||||
BPR_NON_LLGR_STALE
|
||||
BPR_NEIGH_ADDR
|
||||
)
|
||||
|
||||
var BestPathReasonStringMap = map[BestPathReason]string{
|
||||
@@ -68,6 +69,7 @@ var BestPathReasonStringMap = map[BestPathReason]string{
|
||||
BPR_ROUTER_ID: "Router ID",
|
||||
BPR_OLDER: "Older",
|
||||
BPR_NON_LLGR_STALE: "no LLGR Stale",
|
||||
BPR_NEIGH_ADDR: "Neighbor Address",
|
||||
}
|
||||
|
||||
func (r *BestPathReason) String() string {
|
||||
@@ -346,9 +348,6 @@ func (dest *Destination) implicitWithdraw(newPath *Path) {
|
||||
|
||||
func (dest *Destination) computeKnownBestPath() (*Path, BestPathReason, error) {
|
||||
if SelectionOptions.DisableBestPathSelection {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("computeKnownBestPath skipped")
|
||||
return nil, BPR_DISABLED, nil
|
||||
}
|
||||
|
||||
@@ -358,10 +357,6 @@ func (dest *Destination) computeKnownBestPath() (*Path, BestPathReason, error) {
|
||||
return nil, BPR_UNKNOWN, nil
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("computeKnownBestPath knownPathList: %d", len(dest.knownPathList))
|
||||
|
||||
// We pick the first path as current best path. This helps in breaking
|
||||
// tie between two new paths learned in one cycle for which best-path
|
||||
// calculation steps lead to tie.
|
||||
@@ -433,10 +428,9 @@ func (dst *Destination) sort() BestPathReason {
|
||||
better = compareByReachableNexthop(path1, path2)
|
||||
reason = BPR_REACHABLE_NEXT_HOP
|
||||
}
|
||||
if better == nil {
|
||||
better = compareByHighestWeight(path1, path2)
|
||||
reason = BPR_HIGHEST_WEIGHT
|
||||
}
|
||||
|
||||
// compareByHighestWeight was a no-op and was removed.
|
||||
|
||||
if better == nil {
|
||||
better = compareByLocalPref(path1, path2)
|
||||
reason = BPR_LOCAL_PREF
|
||||
@@ -461,25 +455,21 @@ func (dst *Destination) sort() BestPathReason {
|
||||
better = compareByASNumber(path1, path2)
|
||||
reason = BPR_ASN
|
||||
}
|
||||
if better == nil {
|
||||
better = compareByIGPCost(path1, path2)
|
||||
reason = BPR_IGP_COST
|
||||
}
|
||||
|
||||
// compareByIGPCost was a no-op and was removed.
|
||||
|
||||
if better == nil {
|
||||
better = compareByAge(path1, path2)
|
||||
reason = BPR_OLDER
|
||||
}
|
||||
if better == nil {
|
||||
var e error
|
||||
better, e = compareByRouterID(path1, path2)
|
||||
if e != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
"Error": e,
|
||||
}).Error("Could not get best path by comparing router ID")
|
||||
}
|
||||
better, _ = compareByRouterID(path1, path2)
|
||||
reason = BPR_ROUTER_ID
|
||||
}
|
||||
if better == nil {
|
||||
better = compareByNeighborAddress(path1, path2)
|
||||
reason = BPR_NEIGH_ADDR
|
||||
}
|
||||
if better == nil {
|
||||
reason = BPR_UNKNOWN
|
||||
better = path1
|
||||
@@ -616,9 +606,6 @@ func compareByReachableNexthop(path1, path2 *Path) *Path {
|
||||
//
|
||||
// If no path matches this criteria, return nil.
|
||||
// For BGP Nexthop Tracking, evaluates next-hop is validated by IGP.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("enter compareByReachableNexthop -- path1: %s, path2: %s", path1, path2)
|
||||
|
||||
if path1.IsNexthopInvalid && !path2.IsNexthopInvalid {
|
||||
return path2
|
||||
@@ -629,19 +616,6 @@ func compareByReachableNexthop(path1, path2 *Path) *Path {
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareByHighestWeight(path1, path2 *Path) *Path {
|
||||
// Selects a path with highest weight.
|
||||
//
|
||||
// Weight is BGPS specific parameter. It is local to the router on which it
|
||||
// is configured.
|
||||
// Return:
|
||||
// nil if best path among given paths cannot be decided, else best path.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("enter compareByHighestWeight -- path1: %s, path2: %s", path1, path2)
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareByLocalPref(path1, path2 *Path) *Path {
|
||||
// Selects a path with highest local-preference.
|
||||
//
|
||||
@@ -651,9 +625,6 @@ func compareByLocalPref(path1, path2 *Path) *Path {
|
||||
// we return None.
|
||||
//
|
||||
// # Default local-pref values is 100
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByLocalPref")
|
||||
localPref1, _ := path1.GetLocalPref()
|
||||
localPref2, _ := path2.GetLocalPref()
|
||||
// Highest local-preference value is preferred.
|
||||
@@ -674,9 +645,6 @@ func compareByLocalOrigin(path1, path2 *Path) *Path {
|
||||
// Returns None if given paths have same source.
|
||||
//
|
||||
// If both paths are from same sources we cannot compare them here.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByLocalOrigin")
|
||||
if path1.GetSource().Equal(path2.GetSource()) {
|
||||
return nil
|
||||
}
|
||||
@@ -699,34 +667,12 @@ func compareByASPath(path1, path2 *Path) *Path {
|
||||
// Shortest as-path length is preferred. If both path have same lengths,
|
||||
// we return None.
|
||||
if SelectionOptions.IgnoreAsPathLength {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("compareByASPath -- skip")
|
||||
return nil
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByASPath")
|
||||
attribute1 := path1.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
|
||||
attribute2 := path2.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
|
||||
|
||||
// With addpath support, we could compare paths from API don't
|
||||
// AS_PATH. No need to warn here.
|
||||
if !path1.IsLocal() && !path2.IsLocal() && (attribute1 == nil || attribute2 == nil) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
"Key": "compareByASPath",
|
||||
"ASPath1": attribute1,
|
||||
"ASPath2": attribute2,
|
||||
}).Warn("can't compare ASPath because it's not present")
|
||||
}
|
||||
|
||||
l1 := path1.GetAsPathLen()
|
||||
l2 := path2.GetAsPathLen()
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("compareByASPath -- l1: %d, l2: %d", l1, l2)
|
||||
if l1 > l2 {
|
||||
return path2
|
||||
} else if l1 < l2 {
|
||||
@@ -741,27 +687,16 @@ func compareByOrigin(path1, path2 *Path) *Path {
|
||||
//
|
||||
// IGP is preferred over EGP; EGP is preferred over Incomplete.
|
||||
// If both paths have same origin, we return None.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByOrigin")
|
||||
|
||||
attribute1 := path1.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
|
||||
attribute2 := path2.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
|
||||
|
||||
if attribute1 == nil || attribute2 == nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
"Key": "compareByOrigin",
|
||||
"Origin1": attribute1,
|
||||
"Origin2": attribute2,
|
||||
}).Error("can't compare origin because it's not present")
|
||||
return nil
|
||||
}
|
||||
|
||||
origin1 := attribute1.(*bgp.PathAttributeOrigin).Value
|
||||
origin2 := attribute2.(*bgp.PathAttributeOrigin).Value
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("compareByOrigin -- origin1: %d, origin2: %d", origin1, origin2)
|
||||
|
||||
// If both paths have same origins
|
||||
if origin1 == origin2 {
|
||||
@@ -807,9 +742,6 @@ func compareByMED(path1, path2 *Path) *Path {
|
||||
}()
|
||||
|
||||
if SelectionOptions.AlwaysCompareMed || isInternal || isSameAS {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByMED")
|
||||
getMed := func(path *Path) uint32 {
|
||||
attribute := path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
|
||||
if attribute == nil {
|
||||
@@ -821,9 +753,6 @@ func compareByMED(path1, path2 *Path) *Path {
|
||||
|
||||
med1 := getMed(path1)
|
||||
med2 := getMed(path2)
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("compareByMED -- med1: %d, med2: %d", med1, med2)
|
||||
if med1 == med2 {
|
||||
return nil
|
||||
} else if med1 < med2 {
|
||||
@@ -831,9 +760,6 @@ func compareByMED(path1, path2 *Path) *Path {
|
||||
}
|
||||
return path2
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("skip compareByMED %v %v %v", SelectionOptions.AlwaysCompareMed, isInternal, isSameAS)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -844,13 +770,7 @@ func compareByASNumber(path1, path2 *Path) *Path {
|
||||
//
|
||||
//eBGP path is preferred over iBGP. If both paths are from same kind of
|
||||
//peers, return None.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByASNumber")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("compareByASNumber -- p1Asn: %d, p2Asn: %d", path1.GetSource().AS, path2.GetSource().AS)
|
||||
// Path from confederation member should be treated as internal (IBGP learned) path.
|
||||
isIBGP1 := path1.GetSource().Confederation || path1.IsIBGP()
|
||||
isIBGP2 := path2.GetSource().Confederation || path2.IsIBGP()
|
||||
@@ -866,17 +786,6 @@ func compareByASNumber(path1, path2 *Path) *Path {
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareByIGPCost(path1, path2 *Path) *Path {
|
||||
// Select the route with the lowest IGP cost to the next hop.
|
||||
//
|
||||
// Return None if igp cost is same.
|
||||
// Currently BGPS has no concept of IGP and IGP cost.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debugf("enter compareByIGPCost -- path1: %v, path2: %v", path1, path2)
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareByRouterID(path1, path2 *Path) (*Path, error) {
|
||||
// Select the route received from the peer with the lowest BGP router ID.
|
||||
//
|
||||
@@ -884,9 +793,6 @@ func compareByRouterID(path1, path2 *Path) (*Path, error) {
|
||||
// not pick best-path based on this criteria.
|
||||
// RFC: http://tools.ietf.org/html/rfc5004
|
||||
// We pick best path between two iBGP paths as usual.
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
}).Debug("enter compareByRouterID")
|
||||
|
||||
// If both paths are from NC we have same router Id, hence cannot compare.
|
||||
if path1.IsLocal() && path2.IsLocal() {
|
||||
@@ -918,6 +824,28 @@ func compareByRouterID(path1, path2 *Path) (*Path, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func compareByNeighborAddress(path1, path2 *Path) *Path {
|
||||
// Select the route received from the peer with the lowest peer address as
|
||||
// per RFC 4271 9.1.2.2. g
|
||||
|
||||
p1 := path1.GetSource().Address
|
||||
if p1 == nil {
|
||||
return path1
|
||||
}
|
||||
p2 := path2.GetSource().Address
|
||||
if p2 == nil {
|
||||
return path2
|
||||
}
|
||||
|
||||
cmp := bytes.Compare(p1, p2)
|
||||
if cmp < 0 {
|
||||
return path1
|
||||
} else if cmp > 0 {
|
||||
return path2
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareByAge(path1, path2 *Path) *Path {
|
||||
if !path1.IsIBGP() && !path2.IsIBGP() && !SelectionOptions.ExternalCompareRouterId {
|
||||
age1 := path1.GetTimestamp().UnixNano()
|
||||
|
||||
20
vendor/github.com/osrg/gobgp/internal/pkg/table/message.go
generated
vendored
20
vendor/github.com/osrg/gobgp/internal/pkg/table/message.go
generated
vendored
@@ -442,13 +442,29 @@ func (p *packerV4) pack(options ...*bgp.MarshallingOption) []*bgp.BGPMessage {
|
||||
paths := c.paths
|
||||
|
||||
attrs := paths[0].GetPathAttrs()
|
||||
// we can apply a fix here when gobgp receives from MP peer
|
||||
// and propagtes to non-MP peer
|
||||
// we should make sure that next-hop exists in pathattrs
|
||||
// while we build the update message
|
||||
// we do not want to modify the `path` though
|
||||
if paths[0].getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) == nil {
|
||||
attrs = append(attrs, bgp.NewPathAttributeNextHop(paths[0].GetNexthop().String()))
|
||||
}
|
||||
// if we have ever reach here
|
||||
// there is no point keeping MP_REACH_NLRI in the announcement
|
||||
attrs_without_mp := make([]bgp.PathAttributeInterface, 0, len(attrs))
|
||||
for _, attr := range attrs {
|
||||
if attr.GetType() != bgp.BGP_ATTR_TYPE_MP_REACH_NLRI {
|
||||
attrs_without_mp = append(attrs_without_mp, attr)
|
||||
}
|
||||
}
|
||||
attrsLen := 0
|
||||
for _, a := range attrs {
|
||||
for _, a := range attrs_without_mp {
|
||||
attrsLen += a.Len()
|
||||
}
|
||||
|
||||
loop(attrsLen, paths, func(nlris []*bgp.IPAddrPrefix) {
|
||||
msgs = append(msgs, bgp.NewBGPUpdateMessage(nil, attrs, nlris))
|
||||
msgs = append(msgs, bgp.NewBGPUpdateMessage(nil, attrs_without_mp, nlris))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/github.com/osrg/gobgp/internal/pkg/table/path.go
generated
vendored
6
vendor/github.com/osrg/gobgp/internal/pkg/table/path.go
generated
vendored
@@ -1233,12 +1233,12 @@ func nlriToIPNet(nlri bgp.AddrPrefixInterface) *net.IPNet {
|
||||
case *bgp.LabeledIPAddrPrefix:
|
||||
return &net.IPNet{
|
||||
IP: net.IP(T.Prefix.To4()),
|
||||
Mask: net.CIDRMask(int(T.Length), 32),
|
||||
Mask: net.CIDRMask(int(T.Length)-T.Labels.Len()*8, 32),
|
||||
}
|
||||
case *bgp.LabeledIPv6AddrPrefix:
|
||||
return &net.IPNet{
|
||||
IP: net.IP(T.Prefix.To4()),
|
||||
Mask: net.CIDRMask(int(T.Length), 128),
|
||||
IP: net.IP(T.Prefix.To16()),
|
||||
Mask: net.CIDRMask(int(T.Length)-T.Labels.Len()*8, 128),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
57
vendor/github.com/osrg/gobgp/internal/pkg/table/policy.go
generated
vendored
57
vendor/github.com/osrg/gobgp/internal/pkg/table/policy.go
generated
vendored
@@ -1116,7 +1116,7 @@ func ParseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) {
|
||||
return r || s == bgp.VALIDATION_STATE_INVALID.String()
|
||||
}
|
||||
if len(elems) < 2 && (len(elems) < 1 && !isValidationState(elems[0])) {
|
||||
return nil, fmt.Errorf("invalid ext-community (rt|soo):<value> | valid | not-found | invalid")
|
||||
return nil, fmt.Errorf("invalid ext-community (rt|soo|encap|lb):<value> | valid | not-found | invalid")
|
||||
}
|
||||
if isValidationState(elems[0]) {
|
||||
subtype = bgp.EC_SUBTYPE_ORIGIN_VALIDATION
|
||||
@@ -1127,15 +1127,19 @@ func ParseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) {
|
||||
subtype = bgp.EC_SUBTYPE_ROUTE_TARGET
|
||||
case "soo":
|
||||
subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN
|
||||
case "encap":
|
||||
subtype = bgp.EC_SUBTYPE_ENCAPSULATION
|
||||
case "lb":
|
||||
subtype = bgp.EC_SUBTYPE_LINK_BANDWIDTH
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid ext-community (rt|soo):<value> | valid | not-found | invalid")
|
||||
return nil, fmt.Errorf("invalid ext-community (rt|soo|encap|lb):<value> | valid | not-found | invalid")
|
||||
}
|
||||
value = elems[1]
|
||||
}
|
||||
return bgp.ParseExtendedCommunity(subtype, value)
|
||||
}
|
||||
|
||||
var _regexpCommunity2 = regexp.MustCompile(`(\d+.)*\d+:\d+`)
|
||||
var _regexpCommunity2 = regexp.MustCompile(`^(\d+.)*\d+:\d+$`)
|
||||
|
||||
func ParseCommunityRegexp(arg string) (*regexp.Regexp, error) {
|
||||
i, err := strconv.ParseUint(arg, 10, 32)
|
||||
@@ -1160,15 +1164,19 @@ func ParseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *reg
|
||||
var subtype bgp.ExtendedCommunityAttrSubType
|
||||
elems := strings.SplitN(arg, ":", 2)
|
||||
if len(elems) < 2 {
|
||||
return subtype, nil, fmt.Errorf("invalid ext-community format([rt|soo]:<value>)")
|
||||
return subtype, nil, fmt.Errorf("invalid ext-community format([rt|soo|encap|lb]:<value>)")
|
||||
}
|
||||
switch strings.ToLower(elems[0]) {
|
||||
case "rt":
|
||||
subtype = bgp.EC_SUBTYPE_ROUTE_TARGET
|
||||
case "soo":
|
||||
subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN
|
||||
case "encap":
|
||||
subtype = bgp.EC_SUBTYPE_ENCAPSULATION
|
||||
case "lb":
|
||||
subtype = bgp.EC_SUBTYPE_LINK_BANDWIDTH
|
||||
default:
|
||||
return subtype, nil, fmt.Errorf("unknown ext-community subtype. rt, soo is supported")
|
||||
return subtype, nil, fmt.Errorf("unknown ext-community subtype. rt, soo, encap, lb is supported")
|
||||
}
|
||||
exp, err := ParseCommunityRegexp(elems[1])
|
||||
return subtype, exp, err
|
||||
@@ -1212,8 +1220,12 @@ func (s *ExtCommunitySet) List() []string {
|
||||
return fmt.Sprintf("rt:%s", arg)
|
||||
case bgp.EC_SUBTYPE_ROUTE_ORIGIN:
|
||||
return fmt.Sprintf("soo:%s", arg)
|
||||
case bgp.EC_SUBTYPE_ENCAPSULATION:
|
||||
return fmt.Sprintf("encap:%s", arg)
|
||||
case bgp.EC_SUBTYPE_ORIGIN_VALIDATION:
|
||||
return arg
|
||||
case bgp.EC_SUBTYPE_LINK_BANDWIDTH:
|
||||
return fmt.Sprintf("lb:%s", arg)
|
||||
default:
|
||||
return fmt.Sprintf("%d:%s", s.subtypeList[idx], arg)
|
||||
}
|
||||
@@ -1439,11 +1451,17 @@ func (c *PrefixCondition) Option() MatchOption {
|
||||
// subsequent comparison is skipped if that matches the conditions.
|
||||
// If PrefixList's length is zero, return true.
|
||||
func (c *PrefixCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
|
||||
if path.GetRouteFamily() != c.set.family {
|
||||
pathAfi, _ := bgp.RouteFamilyToAfiSafi(path.GetRouteFamily())
|
||||
cAfi, _ := bgp.RouteFamilyToAfiSafi(c.set.family)
|
||||
|
||||
if cAfi != pathAfi {
|
||||
return false
|
||||
}
|
||||
|
||||
r := nlriToIPNet(path.GetNlri())
|
||||
if r == nil {
|
||||
return false
|
||||
}
|
||||
ones, _ := r.Mask.Size()
|
||||
masklen := uint8(ones)
|
||||
result := false
|
||||
@@ -2218,6 +2236,10 @@ func (a *ExtCommunityAction) ToConfig() *config.SetExtCommunity {
|
||||
return fmt.Sprintf("rt:%s", arg)
|
||||
case bgp.EC_SUBTYPE_ROUTE_ORIGIN:
|
||||
return fmt.Sprintf("soo:%s", arg)
|
||||
case bgp.EC_SUBTYPE_ENCAPSULATION:
|
||||
return fmt.Sprintf("encap:%s", arg)
|
||||
case bgp.EC_SUBTYPE_LINK_BANDWIDTH:
|
||||
return fmt.Sprintf("lb:%s", arg)
|
||||
case bgp.EC_SUBTYPE_ORIGIN_VALIDATION:
|
||||
return arg
|
||||
default:
|
||||
@@ -2563,8 +2585,9 @@ func NewAsPathPrependAction(action config.SetAsPathPrepend) (*AsPathPrependActio
|
||||
}
|
||||
|
||||
type NexthopAction struct {
|
||||
value net.IP
|
||||
self bool
|
||||
value net.IP
|
||||
self bool
|
||||
unchanged bool
|
||||
}
|
||||
|
||||
func (a *NexthopAction) Type() ActionType {
|
||||
@@ -2578,6 +2601,12 @@ func (a *NexthopAction) Apply(path *Path, options *PolicyOptions) *Path {
|
||||
}
|
||||
return path
|
||||
}
|
||||
if a.unchanged {
|
||||
if options != nil && options.OldNextHop != nil {
|
||||
path.SetNexthop(options.OldNextHop)
|
||||
}
|
||||
return path
|
||||
}
|
||||
path.SetNexthop(a.value)
|
||||
return path
|
||||
}
|
||||
@@ -2586,6 +2615,9 @@ func (a *NexthopAction) ToConfig() config.BgpNextHopType {
|
||||
if a.self {
|
||||
return config.BgpNextHopType("self")
|
||||
}
|
||||
if a.unchanged {
|
||||
return config.BgpNextHopType("unchanged")
|
||||
}
|
||||
return config.BgpNextHopType(a.value.String())
|
||||
}
|
||||
|
||||
@@ -2605,6 +2637,10 @@ func NewNexthopAction(c config.BgpNextHopType) (*NexthopAction, error) {
|
||||
return &NexthopAction{
|
||||
self: true,
|
||||
}, nil
|
||||
case "unchanged":
|
||||
return &NexthopAction{
|
||||
unchanged: true,
|
||||
}, nil
|
||||
}
|
||||
addr := net.ParseIP(string(c))
|
||||
if addr == nil {
|
||||
@@ -4046,6 +4082,11 @@ func toStatementApi(s *config.Statement) *api.Statement {
|
||||
Self: true,
|
||||
}
|
||||
}
|
||||
if string(s.Actions.BgpActions.SetNextHop) == "unchanged" {
|
||||
return &api.NexthopAction{
|
||||
Unchanged: true,
|
||||
}
|
||||
}
|
||||
return &api.NexthopAction{
|
||||
Address: string(s.Actions.BgpActions.SetNextHop),
|
||||
}
|
||||
|
||||
21
vendor/github.com/osrg/gobgp/internal/pkg/table/table.go
generated
vendored
21
vendor/github.com/osrg/gobgp/internal/pkg/table/table.go
generated
vendored
@@ -209,6 +209,7 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error)
|
||||
switch t.routeFamily {
|
||||
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC, bgp.RF_IPv4_MPLS, bgp.RF_IPv6_MPLS:
|
||||
_, prefix, err := net.ParseCIDR(key)
|
||||
ones, bits := prefix.Mask.Size()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -216,7 +217,25 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error)
|
||||
for _, dst := range t.GetDestinations() {
|
||||
r.Add(nlriToIPNet(dst.nlri), dst)
|
||||
}
|
||||
r.WalkPrefix(prefix, func(_ *net.IPNet, v interface{}) bool {
|
||||
p := &net.IPNet{
|
||||
IP: prefix.IP,
|
||||
Mask: net.CIDRMask((ones>>3)<<3, bits),
|
||||
}
|
||||
mask := 0
|
||||
div := 0
|
||||
if ones%8 != 0 {
|
||||
mask = 8 - ones&0x7
|
||||
div = ones >> 3
|
||||
}
|
||||
r.WalkPrefix(p, func(n *net.IPNet, v interface{}) bool {
|
||||
if mask != 0 && n.IP[div]>>mask != p.IP[div]>>mask {
|
||||
return true
|
||||
}
|
||||
l, _ := n.Mask.Size()
|
||||
|
||||
if ones > l {
|
||||
return true
|
||||
}
|
||||
results = append(results, v.(*Destination))
|
||||
return true
|
||||
})
|
||||
|
||||
11
vendor/github.com/osrg/gobgp/internal/pkg/table/table_manager.go
generated
vendored
11
vendor/github.com/osrg/gobgp/internal/pkg/table/table_manager.go
generated
vendored
@@ -60,6 +60,8 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time)
|
||||
l = append(l, a.Value...)
|
||||
dels = append(dels, l...)
|
||||
default:
|
||||
// update msg may not contain next_hop (type:3) in attr
|
||||
// due to it uses MpReachNLRI and it also has empty update.NLRI
|
||||
attrs = append(attrs, attr)
|
||||
}
|
||||
}
|
||||
@@ -92,6 +94,11 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time)
|
||||
reachAttrs[len(reachAttrs)-1] = reach
|
||||
|
||||
for _, nlri := range reach.Value {
|
||||
// when build path from reach
|
||||
// reachAttrs might not contain next_hop if `attrs` does not have one
|
||||
// this happens when a MP peer send update to gobgp
|
||||
// However nlri is always populated because how we build the path
|
||||
// path.info{nlri: nlri}
|
||||
p := NewPath(peerInfo, nlri, false, reachAttrs, timestamp, false)
|
||||
p.SetHash(hash)
|
||||
pathList = append(pathList, p)
|
||||
@@ -179,8 +186,8 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) {
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func (tm *TableManager) update(newPath *Path) *Update {
|
||||
t := tm.Tables[newPath.GetRouteFamily()]
|
||||
func (manager *TableManager) update(newPath *Path) *Update {
|
||||
t := manager.Tables[newPath.GetRouteFamily()]
|
||||
t.validatePath(newPath)
|
||||
dst := t.getOrCreateDest(newPath.GetNlri(), 64)
|
||||
u := dst.Calculate(newPath)
|
||||
|
||||
140
vendor/github.com/osrg/gobgp/internal/pkg/zebra/apitype_string.go
generated
vendored
140
vendor/github.com/osrg/gobgp/internal/pkg/zebra/apitype_string.go
generated
vendored
@@ -57,71 +57,87 @@ func _() {
|
||||
_ = x[_mplsLabelsAdd-46]
|
||||
_ = x[_mplsLabelsDelete-47]
|
||||
_ = x[_mplsLabelsReplace-48]
|
||||
_ = x[_ipmrRouteStats-49]
|
||||
_ = x[labelManagerConnect-50]
|
||||
_ = x[labelManagerConnectAsync-51]
|
||||
_ = x[getLabelChunk-52]
|
||||
_ = x[releaseLabelChunk-53]
|
||||
_ = x[_fecRegister-54]
|
||||
_ = x[_fecUnregister-55]
|
||||
_ = x[_fecUpdate-56]
|
||||
_ = x[_advertiseDefaultGW-57]
|
||||
_ = x[_advertiseSviMACIP-58]
|
||||
_ = x[_advertiseSubnet-59]
|
||||
_ = x[_advertiseAllVNI-60]
|
||||
_ = x[_localESAdd-61]
|
||||
_ = x[_localESDel-62]
|
||||
_ = x[_vniAdd-63]
|
||||
_ = x[_vniDel-64]
|
||||
_ = x[_l3VNIAdd-65]
|
||||
_ = x[_l3VNIDel-66]
|
||||
_ = x[_remoteVTEPAdd-67]
|
||||
_ = x[_remoteVTEPDel-68]
|
||||
_ = x[_macIPAdd-69]
|
||||
_ = x[_macIPDel-70]
|
||||
_ = x[_ipPrefixRouteAdd-71]
|
||||
_ = x[_ipPrefixRouteDel-72]
|
||||
_ = x[_remoteMACIPAdd-73]
|
||||
_ = x[_remoteMACIPDel-74]
|
||||
_ = x[_duplicateAddrDetection-75]
|
||||
_ = x[_pwAdd-76]
|
||||
_ = x[_pwDelete-77]
|
||||
_ = x[_pwSet-78]
|
||||
_ = x[_pwUnset-79]
|
||||
_ = x[_pwStatusUpdate-80]
|
||||
_ = x[_ruleAdd-81]
|
||||
_ = x[_ruleDelete-82]
|
||||
_ = x[_ruleNotifyOwner-83]
|
||||
_ = x[_tableManagerConnect-84]
|
||||
_ = x[_getTableChunk-85]
|
||||
_ = x[_releaseTableChunk-86]
|
||||
_ = x[_ipSetCreate-87]
|
||||
_ = x[_ipSetDestroy-88]
|
||||
_ = x[_ipSetEntryAdd-89]
|
||||
_ = x[_ipSetEntryDelete-90]
|
||||
_ = x[_ipSetNotifyOwner-91]
|
||||
_ = x[_ipSetEntryNotifyOwner-92]
|
||||
_ = x[_ipTableAdd-93]
|
||||
_ = x[_ipTableDelete-94]
|
||||
_ = x[_ipTableNotifyOwner-95]
|
||||
_ = x[_vxlanFloodControl-96]
|
||||
_ = x[_vxlanSgAdd-97]
|
||||
_ = x[_vxlanSgDel-98]
|
||||
_ = x[_vxlanSgReplay-99]
|
||||
_ = x[_mlagProcessUp-100]
|
||||
_ = x[_mlagProcessDown-101]
|
||||
_ = x[_mlagClientRegister-102]
|
||||
_ = x[_mlagClientUnregister-103]
|
||||
_ = x[_mlagClientForwardMsg-104]
|
||||
_ = x[zebraError-105]
|
||||
_ = x[_clientCapabilities-106]
|
||||
_ = x[BackwardIPv6RouteAdd-107]
|
||||
_ = x[BackwardIPv6RouteDelete-108]
|
||||
_ = x[_srPolicySet-49]
|
||||
_ = x[_srPolicyDelete-50]
|
||||
_ = x[_srPolicyNotifyStatus-51]
|
||||
_ = x[_ipmrRouteStats-52]
|
||||
_ = x[labelManagerConnect-53]
|
||||
_ = x[labelManagerConnectAsync-54]
|
||||
_ = x[getLabelChunk-55]
|
||||
_ = x[releaseLabelChunk-56]
|
||||
_ = x[_fecRegister-57]
|
||||
_ = x[_fecUnregister-58]
|
||||
_ = x[_fecUpdate-59]
|
||||
_ = x[_advertiseDefaultGW-60]
|
||||
_ = x[_advertiseSviMACIP-61]
|
||||
_ = x[_advertiseSubnet-62]
|
||||
_ = x[_advertiseAllVNI-63]
|
||||
_ = x[_localESAdd-64]
|
||||
_ = x[_localESDel-65]
|
||||
_ = x[_remoteESVTEPAdd-66]
|
||||
_ = x[_remoteESVTEPDel-67]
|
||||
_ = x[_localESEVIAdd-68]
|
||||
_ = x[_localESEVIDel-69]
|
||||
_ = x[_vniAdd-70]
|
||||
_ = x[_vniDel-71]
|
||||
_ = x[_l3VNIAdd-72]
|
||||
_ = x[_l3VNIDel-73]
|
||||
_ = x[_remoteVTEPAdd-74]
|
||||
_ = x[_remoteVTEPDel-75]
|
||||
_ = x[_macIPAdd-76]
|
||||
_ = x[_macIPDel-77]
|
||||
_ = x[_ipPrefixRouteAdd-78]
|
||||
_ = x[_ipPrefixRouteDel-79]
|
||||
_ = x[_remoteMACIPAdd-80]
|
||||
_ = x[_remoteMACIPDel-81]
|
||||
_ = x[_duplicateAddrDetection-82]
|
||||
_ = x[_pwAdd-83]
|
||||
_ = x[_pwDelete-84]
|
||||
_ = x[_pwSet-85]
|
||||
_ = x[_pwUnset-86]
|
||||
_ = x[_pwStatusUpdate-87]
|
||||
_ = x[_ruleAdd-88]
|
||||
_ = x[_ruleDelete-89]
|
||||
_ = x[_ruleNotifyOwner-90]
|
||||
_ = x[_tableManagerConnect-91]
|
||||
_ = x[_getTableChunk-92]
|
||||
_ = x[_releaseTableChunk-93]
|
||||
_ = x[_ipSetCreate-94]
|
||||
_ = x[_ipSetDestroy-95]
|
||||
_ = x[_ipSetEntryAdd-96]
|
||||
_ = x[_ipSetEntryDelete-97]
|
||||
_ = x[_ipSetNotifyOwner-98]
|
||||
_ = x[_ipSetEntryNotifyOwner-99]
|
||||
_ = x[_ipTableAdd-100]
|
||||
_ = x[_ipTableDelete-101]
|
||||
_ = x[_ipTableNotifyOwner-102]
|
||||
_ = x[_vxlanFloodControl-103]
|
||||
_ = x[_vxlanSgAdd-104]
|
||||
_ = x[_vxlanSgDel-105]
|
||||
_ = x[_vxlanSgReplay-106]
|
||||
_ = x[_mlagProcessUp-107]
|
||||
_ = x[_mlagProcessDown-108]
|
||||
_ = x[_mlagClientRegister-109]
|
||||
_ = x[_mlagClientUnregister-110]
|
||||
_ = x[_mlagClientForwardMsg-111]
|
||||
_ = x[zebraError-112]
|
||||
_ = x[_clientCapabilities-113]
|
||||
_ = x[_opaqueMessage-114]
|
||||
_ = x[_opaqueRegister-115]
|
||||
_ = x[_opaqueUnregister-116]
|
||||
_ = x[_neighDiscover-117]
|
||||
_ = x[BackwardIPv6RouteAdd-118]
|
||||
_ = x[BackwardIPv6RouteDelete-119]
|
||||
_ = x[zapi6Frr7dot3MinDifferentAPIType-49]
|
||||
_ = x[zapi6Frr7dot2MinDifferentAPIType-48]
|
||||
_ = x[zapi5ClMinDifferentAPIType-19]
|
||||
_ = x[zapi5MinDifferentAPIType-7]
|
||||
_ = x[zapi4MinDifferentAPIType-6]
|
||||
_ = x[zapi3MinDifferentAPIType-0]
|
||||
_ = x[zapi6Frr7dot3LabelManagerConnect-50]
|
||||
_ = x[zapi6Frr7dot3LabelManagerConnectAsync-51]
|
||||
_ = x[zapi6Frr7dot3GetLabelChunk-52]
|
||||
_ = x[zapi6Frr7dot3ReleaseLabelChunk-53]
|
||||
_ = x[zapi6Frr7dot2LabelManagerConnect-49]
|
||||
_ = x[zapi6Frr7dot2LabelManagerConnectAsync-50]
|
||||
_ = x[zapi6Frr7dot2GetLabelChunk-51]
|
||||
@@ -212,9 +228,9 @@ func _() {
|
||||
_ = x[zapi3NexthopUpdate-29]
|
||||
}
|
||||
|
||||
const _APIType_name = "interfaceAddinterfaceDeleteinterfaceAddressAddinterfaceAddressDeleteinterfaceUpinterfaceDown_interfaceSetMaster_interfaceSetProtoDownRouteAddRouteDelete_routeNotifyOwnerredistributeAdd_redistributeDelete_redistributeDefaultAdd_redistributeDefaultDeleterouterIDAdd_routerIDDeleterouterIDUpdatehello_capabilitiesnexthopRegisternexthopUnregisternexthopUpdate_interfaceNBRAddressAdd_interfaceNBRAddressDelete_interfaceBFDDestUpdate_importRouteRegister_importRouteUnregister_importCheckUpdate_bfdDestRegister_bfdDestDeregister_bfdDestUpdate_bfdDestReplayredistributeRouteAddredistributeRouteDel_vrfUnregister_vrfAdd_vrfDeletevrfLabel_interfaceVRFUpdate_bfdClientRegister_bfdClientDeregister_interfaceEnableRADV_interfaceDisableRADVipv4NexthopLookupMRIB_interfaceLinkParams_mplsLabelsAdd_mplsLabelsDelete_mplsLabelsReplace_ipmrRouteStatslabelManagerConnectlabelManagerConnectAsyncgetLabelChunkreleaseLabelChunk_fecRegister_fecUnregister_fecUpdate_advertiseDefaultGW_advertiseSviMACIP_advertiseSubnet_advertiseAllVNI_localESAdd_localESDel_vniAdd_vniDel_l3VNIAdd_l3VNIDel_remoteVTEPAdd_remoteVTEPDel_macIPAdd_macIPDel_ipPrefixRouteAdd_ipPrefixRouteDel_remoteMACIPAdd_remoteMACIPDel_duplicateAddrDetection_pwAdd_pwDelete_pwSet_pwUnset_pwStatusUpdate_ruleAdd_ruleDelete_ruleNotifyOwner_tableManagerConnect_getTableChunk_releaseTableChunk_ipSetCreate_ipSetDestroy_ipSetEntryAdd_ipSetEntryDelete_ipSetNotifyOwner_ipSetEntryNotifyOwner_ipTableAdd_ipTableDelete_ipTableNotifyOwner_vxlanFloodControl_vxlanSgAdd_vxlanSgDel_vxlanSgReplay_mlagProcessUp_mlagProcessDown_mlagClientRegister_mlagClientUnregister_mlagClientForwardMsgzebraError_clientCapabilitiesBackwardIPv6RouteAddBackwardIPv6RouteDelete"
|
||||
const _APIType_name = "interfaceAddinterfaceDeleteinterfaceAddressAddinterfaceAddressDeleteinterfaceUpinterfaceDown_interfaceSetMaster_interfaceSetProtoDownRouteAddRouteDelete_routeNotifyOwnerredistributeAdd_redistributeDelete_redistributeDefaultAdd_redistributeDefaultDeleterouterIDAdd_routerIDDeleterouterIDUpdatehello_capabilitiesnexthopRegisternexthopUnregisternexthopUpdate_interfaceNBRAddressAdd_interfaceNBRAddressDelete_interfaceBFDDestUpdate_importRouteRegister_importRouteUnregister_importCheckUpdate_bfdDestRegister_bfdDestDeregister_bfdDestUpdate_bfdDestReplayredistributeRouteAddredistributeRouteDel_vrfUnregister_vrfAdd_vrfDeletevrfLabel_interfaceVRFUpdate_bfdClientRegister_bfdClientDeregister_interfaceEnableRADV_interfaceDisableRADVipv4NexthopLookupMRIB_interfaceLinkParams_mplsLabelsAdd_mplsLabelsDelete_mplsLabelsReplace_srPolicySet_srPolicyDelete_srPolicyNotifyStatus_ipmrRouteStatslabelManagerConnectlabelManagerConnectAsyncgetLabelChunkreleaseLabelChunk_fecRegister_fecUnregister_fecUpdate_advertiseDefaultGW_advertiseSviMACIP_advertiseSubnet_advertiseAllVNI_localESAdd_localESDel_remoteESVTEPAdd_remoteESVTEPDel_localESEVIAdd_localESEVIDel_vniAdd_vniDel_l3VNIAdd_l3VNIDel_remoteVTEPAdd_remoteVTEPDel_macIPAdd_macIPDel_ipPrefixRouteAdd_ipPrefixRouteDel_remoteMACIPAdd_remoteMACIPDel_duplicateAddrDetection_pwAdd_pwDelete_pwSet_pwUnset_pwStatusUpdate_ruleAdd_ruleDelete_ruleNotifyOwner_tableManagerConnect_getTableChunk_releaseTableChunk_ipSetCreate_ipSetDestroy_ipSetEntryAdd_ipSetEntryDelete_ipSetNotifyOwner_ipSetEntryNotifyOwner_ipTableAdd_ipTableDelete_ipTableNotifyOwner_vxlanFloodControl_vxlanSgAdd_vxlanSgDel_vxlanSgReplay_mlagProcessUp_mlagProcessDown_mlagClientRegister_mlagClientUnregister_mlagClientForwardMsgzebraError_clientCapabilities_opaqueMessage_opaqueRegister_opaqueUnregister_neighDiscoverBackwardIPv6RouteAddBackwardIPv6RouteDelete"
|
||||
|
||||
var _APIType_index = [...]uint16{0, 12, 27, 46, 68, 79, 92, 111, 133, 141, 152, 169, 184, 203, 226, 252, 263, 278, 292, 297, 310, 325, 342, 355, 378, 404, 427, 447, 469, 487, 503, 521, 535, 549, 569, 589, 603, 610, 620, 628, 647, 665, 685, 705, 726, 747, 767, 781, 798, 816, 831, 850, 874, 887, 904, 916, 930, 940, 959, 977, 993, 1009, 1020, 1031, 1038, 1045, 1054, 1063, 1077, 1091, 1100, 1109, 1126, 1143, 1158, 1173, 1196, 1202, 1211, 1217, 1225, 1240, 1248, 1259, 1275, 1295, 1309, 1327, 1339, 1352, 1366, 1383, 1400, 1422, 1433, 1447, 1466, 1484, 1495, 1506, 1520, 1534, 1550, 1569, 1590, 1611, 1621, 1640, 1660, 1683}
|
||||
var _APIType_index = [...]uint16{0, 12, 27, 46, 68, 79, 92, 111, 133, 141, 152, 169, 184, 203, 226, 252, 263, 278, 292, 297, 310, 325, 342, 355, 378, 404, 427, 447, 469, 487, 503, 521, 535, 549, 569, 589, 603, 610, 620, 628, 647, 665, 685, 705, 726, 747, 767, 781, 798, 816, 828, 843, 864, 879, 898, 922, 935, 952, 964, 978, 988, 1007, 1025, 1041, 1057, 1068, 1079, 1095, 1111, 1125, 1139, 1146, 1153, 1162, 1171, 1185, 1199, 1208, 1217, 1234, 1251, 1266, 1281, 1304, 1310, 1319, 1325, 1333, 1348, 1356, 1367, 1383, 1403, 1417, 1435, 1447, 1460, 1474, 1491, 1508, 1530, 1541, 1555, 1574, 1592, 1603, 1614, 1628, 1642, 1658, 1677, 1698, 1719, 1729, 1748, 1762, 1777, 1794, 1808, 1828, 1851}
|
||||
|
||||
func (i APIType) String() string {
|
||||
if i >= APIType(len(_APIType_index)-1) {
|
||||
|
||||
10
vendor/github.com/osrg/gobgp/internal/pkg/zebra/routetype_string.go
generated
vendored
10
vendor/github.com/osrg/gobgp/internal/pkg/zebra/routetype_string.go
generated
vendored
@@ -37,13 +37,15 @@ func _() {
|
||||
_ = x[routeOpenfabric-26]
|
||||
_ = x[routeVRRP-27]
|
||||
_ = x[routeNHG-28]
|
||||
_ = x[routeAll-29]
|
||||
_ = x[routeMax-30]
|
||||
_ = x[routeSRTE-29]
|
||||
_ = x[routeAll-30]
|
||||
_ = x[routeMax-31]
|
||||
_ = x[zapi5Frr4RouteAll-24]
|
||||
_ = x[zapi5Frr5RouteAll-25]
|
||||
_ = x[zapi6Frr6RouteAll-26]
|
||||
_ = x[zapi6Frr7RouteAll-27]
|
||||
_ = x[zapi6Frr7dot2RouteAll-28]
|
||||
_ = x[zapi6Frr7dot3RouteAll-29]
|
||||
_ = x[zapi4RouteNHRP-11]
|
||||
_ = x[zapi4RouteHSLS-12]
|
||||
_ = x[zapi4RouteOLSR-13]
|
||||
@@ -61,9 +63,9 @@ func _() {
|
||||
_ = x[zapi3RouteNHRP-14]
|
||||
}
|
||||
|
||||
const _RouteType_name = "routeSystemrouteKernelrouteConnectRouteStaticrouteRIProuteRIPNGrouteOSPFrouteOSPF6routeISISRouteBGProutePIMrouteEIGRProuteNHRProuteHSLSrouteOLSRrouteTABLErouteLDProuteVNCrouteVNCDirectrouteVNCDirectRHrouteBGPDirectrouteBGPDirectEXTrouteBABELrouteSHARProutePBRrouteBFDrouteOpenfabricrouteVRRProuteNHGrouteAllrouteMax"
|
||||
const _RouteType_name = "routeSystemrouteKernelrouteConnectRouteStaticrouteRIProuteRIPNGrouteOSPFrouteOSPF6routeISISRouteBGProutePIMrouteEIGRProuteNHRProuteHSLSrouteOLSRrouteTABLErouteLDProuteVNCrouteVNCDirectrouteVNCDirectRHrouteBGPDirectrouteBGPDirectEXTrouteBABELrouteSHARProutePBRrouteBFDrouteOpenfabricrouteVRRProuteNHGrouteSRTErouteAllrouteMax"
|
||||
|
||||
var _RouteType_index = [...]uint16{0, 11, 22, 34, 45, 53, 63, 72, 82, 91, 99, 107, 117, 126, 135, 144, 154, 162, 170, 184, 200, 214, 231, 241, 251, 259, 267, 282, 291, 299, 307, 315}
|
||||
var _RouteType_index = [...]uint16{0, 11, 22, 34, 45, 53, 63, 72, 82, 91, 99, 107, 117, 126, 135, 144, 154, 162, 170, 184, 200, 214, 231, 241, 251, 259, 267, 282, 291, 299, 308, 316, 324}
|
||||
|
||||
func (i RouteType) String() string {
|
||||
if i >= RouteType(len(_RouteType_index)-1) {
|
||||
|
||||
353
vendor/github.com/osrg/gobgp/internal/pkg/zebra/zapi.go
generated
vendored
353
vendor/github.com/osrg/gobgp/internal/pkg/zebra/zapi.go
generated
vendored
@@ -115,8 +115,8 @@ const (
|
||||
const softwareNameMinimumVersion uint8 = 5
|
||||
|
||||
var allowableSoftwareNameArrays = [][]string{
|
||||
{"frr4", "cumulus"}, //version:5
|
||||
{"frr7.2", "frr7", "frr6"}, //version:6
|
||||
{"frr4", "cumulus"}, //version:5
|
||||
{"frr7.3", "frr7.2", "frr7", "frr6"}, //version:6
|
||||
}
|
||||
|
||||
// IsAllowableSoftwareName returns bool from version number and softwareName
|
||||
@@ -317,71 +317,83 @@ const (
|
||||
_interfaceLinkParams
|
||||
_mplsLabelsAdd
|
||||
_mplsLabelsDelete
|
||||
_mplsLabelsReplace // add in frr7.3
|
||||
_mplsLabelsReplace // add in frr7.3
|
||||
_srPolicySet // add in frr7.5
|
||||
_srPolicyDelete // 50 // add in frr7.5
|
||||
_srPolicyNotifyStatus // add in frr7.5
|
||||
_ipmrRouteStats
|
||||
labelManagerConnect // 50
|
||||
labelManagerConnect // 53
|
||||
labelManagerConnectAsync // add in frr5
|
||||
getLabelChunk
|
||||
releaseLabelChunk
|
||||
_fecRegister
|
||||
_fecUnregister
|
||||
_fecUpdate
|
||||
_advertiseDefaultGW
|
||||
_advertiseSviMACIP // add in frr7.1
|
||||
_advertiseDefaultGW // 60
|
||||
_advertiseSviMACIP // add in frr7.1
|
||||
_advertiseSubnet
|
||||
_advertiseAllVNI // 60
|
||||
_advertiseAllVNI // 63
|
||||
_localESAdd
|
||||
_localESDel
|
||||
_vniAdd
|
||||
_localESDel // 65
|
||||
_remoteESVTEPAdd // add in frr7.5
|
||||
_remoteESVTEPDel // add in frr7.5
|
||||
_localESEVIAdd // add in frr7.5
|
||||
_localESEVIDel // add in frr7.5
|
||||
_vniAdd // 70
|
||||
_vniDel
|
||||
_l3VNIAdd
|
||||
_l3VNIDel
|
||||
_remoteVTEPAdd
|
||||
_remoteVTEPDel
|
||||
_macIPAdd
|
||||
_macIPDel // 70
|
||||
_macIPDel // 77
|
||||
_ipPrefixRouteAdd
|
||||
_ipPrefixRouteDel
|
||||
_remoteMACIPAdd
|
||||
_remoteMACIPAdd // 80
|
||||
_remoteMACIPDel
|
||||
_duplicateAddrDetection
|
||||
_pwAdd
|
||||
_pwDelete
|
||||
_pwSet
|
||||
_pwUnset
|
||||
_pwStatusUpdate // 80
|
||||
_pwStatusUpdate // 87
|
||||
_ruleAdd
|
||||
_ruleDelete
|
||||
_ruleNotifyOwner
|
||||
_ruleNotifyOwner // 90
|
||||
_tableManagerConnect
|
||||
_getTableChunk
|
||||
_releaseTableChunk
|
||||
_ipSetCreate
|
||||
_ipSetDestroy
|
||||
_ipSetEntryAdd
|
||||
_ipSetEntryDelete // 90
|
||||
_ipSetEntryDelete // 97
|
||||
_ipSetNotifyOwner
|
||||
_ipSetEntryNotifyOwner
|
||||
_ipTableAdd
|
||||
_ipTableAdd // 100
|
||||
_ipTableDelete
|
||||
_ipTableNotifyOwner
|
||||
_vxlanFloodControl
|
||||
_vxlanSgAdd
|
||||
_vxlanSgDel
|
||||
_vxlanSgReplay
|
||||
_mlagProcessUp // 100 // add in frr7.3
|
||||
_mlagProcessUp // 107 // add in frr7.3
|
||||
_mlagProcessDown // add in frr7.3
|
||||
_mlagClientRegister // add in frr7.3
|
||||
_mlagClientUnregister // add in frr7.3
|
||||
_mlagClientUnregister // 110 // add in frr7.3
|
||||
_mlagClientForwardMsg // add in frr7.3
|
||||
zebraError // add in frr7.3
|
||||
_clientCapabilities // add in frr7.4
|
||||
_opaqueMessage // add in frr7.5
|
||||
_opaqueRegister // add in frr7.5
|
||||
_opaqueUnregister // add in frr7.5
|
||||
_neighDiscover // 117 // add in frr7.5
|
||||
// BackwardIPv6RouteAdd is referred in zclient_test
|
||||
BackwardIPv6RouteAdd // quagga, frr3, frr4, frr5
|
||||
// BackwardIPv6RouteDelete is referred in zclient_test
|
||||
BackwardIPv6RouteDelete // quagga, frr3, frr4, frr5
|
||||
)
|
||||
const (
|
||||
zapi6Frr7dot3MinDifferentAPIType APIType = 49 //frr7.3(zapi6)
|
||||
zapi6Frr7dot2MinDifferentAPIType APIType = 48 //frr7.2(zapi6)
|
||||
zapi5ClMinDifferentAPIType APIType = 19 //cumuluslinux3.7.7, zebra4.0+cl3u13(zapi5)
|
||||
zapi5MinDifferentAPIType APIType = 7 //frr4&5(zapi5), frr6&7.0&7.1(zapi6)
|
||||
@@ -399,15 +411,31 @@ func minDifferentAPIType(version uint8, softwareName string) APIType {
|
||||
} else if version == 5 ||
|
||||
(version == 6 && (softwareName == "frr6" || softwareName == "frr7")) {
|
||||
return zapi5MinDifferentAPIType
|
||||
} else if version == 6 && softwareName == "frr7.2" {
|
||||
return zapi6Frr7dot2MinDifferentAPIType
|
||||
}
|
||||
return zapi6Frr7dot2MinDifferentAPIType
|
||||
return zapi6Frr7dot3MinDifferentAPIType
|
||||
}
|
||||
|
||||
const (
|
||||
zapi6Frr7dot2LabelManagerConnect APIType = 49 // difference from frr7.3
|
||||
zapi6Frr7dot2LabelManagerConnectAsync APIType = 50 // difference from frr7.3
|
||||
zapi6Frr7dot2GetLabelChunk APIType = 51 // difference from frr7.3
|
||||
zapi6Frr7dot2ReleaseLabelChunk APIType = 52 // difference from frr7.3
|
||||
zapi6Frr7dot3LabelManagerConnect APIType = 50 // difference from frr7.5
|
||||
zapi6Frr7dot3LabelManagerConnectAsync APIType = 51 // difference from frr7.5
|
||||
zapi6Frr7dot3GetLabelChunk APIType = 52 // difference from frr7.5
|
||||
zapi6Frr7dot3ReleaseLabelChunk APIType = 53 // difference from frr7.5
|
||||
)
|
||||
|
||||
var apiTypeZapi6Frr7dot3Map = map[APIType]APIType{
|
||||
labelManagerConnect: zapi6Frr7dot3LabelManagerConnect,
|
||||
labelManagerConnectAsync: zapi6Frr7dot3LabelManagerConnectAsync,
|
||||
getLabelChunk: zapi6Frr7dot3GetLabelChunk,
|
||||
releaseLabelChunk: zapi6Frr7dot3ReleaseLabelChunk,
|
||||
}
|
||||
|
||||
const (
|
||||
zapi6Frr7dot2LabelManagerConnect APIType = 49 // difference from frr7.5
|
||||
zapi6Frr7dot2LabelManagerConnectAsync APIType = 50 // difference from frr7.5
|
||||
zapi6Frr7dot2GetLabelChunk APIType = 51 // difference from frr7.5
|
||||
zapi6Frr7dot2ReleaseLabelChunk APIType = 52 // difference from frr7.5
|
||||
)
|
||||
|
||||
var apiTypeZapi6Frr7dot2Map = map[APIType]APIType{
|
||||
@@ -656,7 +684,9 @@ func (t APIType) doesNeedConversion(version uint8, softwareName string) bool {
|
||||
return true
|
||||
}
|
||||
func apiTypeMap(version uint8, softwareName string) map[APIType]APIType {
|
||||
if version == 6 && softwareName == "frr7" {
|
||||
if version == 6 && softwareName == "frr7.2" {
|
||||
return apiTypeZapi6Frr7dot2Map
|
||||
} else if version == 6 && softwareName == "frr7" {
|
||||
return apiTypeZapi6Frr7Map
|
||||
} else if version == 6 && softwareName == "frr6" {
|
||||
return apiTypeZapi6Frr6Map
|
||||
@@ -672,7 +702,7 @@ func apiTypeMap(version uint8, softwareName string) map[APIType]APIType {
|
||||
} else if version < 4 {
|
||||
return apiTypeZapi3Map
|
||||
}
|
||||
return apiTypeZapi6Frr7dot2Map
|
||||
return apiTypeZapi6Frr7dot3Map
|
||||
}
|
||||
|
||||
// ToEach is referred in zclient_test
|
||||
@@ -762,6 +792,7 @@ const (
|
||||
routeOpenfabric // FRRRouting version 7 (Zapi6) adds.
|
||||
routeVRRP // FRRRouting version 7.2 (Zapi6) adds.
|
||||
routeNHG // FRRRouting version 7.3 (Zapi6) adds.
|
||||
routeSRTE // FRRRouting version 7.5 (Zapi6) adds.
|
||||
routeAll
|
||||
routeMax // max value for error
|
||||
)
|
||||
@@ -771,6 +802,7 @@ const (
|
||||
zapi6Frr6RouteAll RouteType = 26
|
||||
zapi6Frr7RouteAll RouteType = 27
|
||||
zapi6Frr7dot2RouteAll RouteType = 28
|
||||
zapi6Frr7dot3RouteAll RouteType = 29
|
||||
)
|
||||
|
||||
func getRouteAll(version uint8, softwareName string) RouteType {
|
||||
@@ -786,6 +818,8 @@ func getRouteAll(version uint8, softwareName string) RouteType {
|
||||
return zapi6Frr7RouteAll
|
||||
} else if softwareName == "frr7.2" {
|
||||
return zapi6Frr7dot2RouteAll
|
||||
} else if softwareName == "frr7.3" {
|
||||
return zapi6Frr7dot3RouteAll
|
||||
}
|
||||
}
|
||||
return routeAll
|
||||
@@ -881,6 +915,7 @@ var routeTypeValueMap = map[string]RouteType{
|
||||
"openfabric": routeOpenfabric, // add in frr7.0(zapi6)
|
||||
"vrrp": routeVRRP, // add in frr7.2(zapi6)
|
||||
"nhg": routeNHG, // add in frr7.3(zapi6)
|
||||
"srte": routeSRTE, // add in frr7.5(zapi6)
|
||||
"wildcard": routeAll,
|
||||
}
|
||||
|
||||
@@ -918,7 +953,7 @@ func ipFromFamily(family uint8, buf []byte) net.IP {
|
||||
}
|
||||
|
||||
// MessageFlag is the type of API Message Flags.
|
||||
type MessageFlag uint8
|
||||
type MessageFlag uint32 // MESSAGE_FLAG is 32bit after frr7.5, 8bit before frr7.4
|
||||
|
||||
const ( // For FRRouting version 4, 5 and 6 (ZAPI version 5 and 6).
|
||||
// MessageNexthop is referred in zclient
|
||||
@@ -932,9 +967,10 @@ const ( // For FRRouting version 4, 5 and 6 (ZAPI version 5 and 6).
|
||||
MessageMTU MessageFlag = 0x10
|
||||
messageSRCPFX MessageFlag = 0x20
|
||||
// MessageLabel is referred in zclient
|
||||
MessageLabel MessageFlag = 0x40 // deleted in frr7.3
|
||||
messageBackupNexthops MessageFlag = 0x40 // added in frr7.4
|
||||
messageTableID MessageFlag = 0x80 // introduced in frr5
|
||||
MessageLabel MessageFlag = 0x40 // deleted in frr7.3
|
||||
messageBackupNexthops MessageFlag = 0x40 // added in frr7.4
|
||||
messageTableID MessageFlag = 0x80 // introduced in frr5
|
||||
messageSRTE MessageFlag = 0x100 // introduced in frr7.5
|
||||
)
|
||||
|
||||
const ( // For FRRouting.
|
||||
@@ -993,7 +1029,7 @@ func (f MessageFlag) string(version uint8, softwareName string) string {
|
||||
if version > 3 && f&messageSRCPFX.ToEach(version) > 0 {
|
||||
ss = append(ss, "SRCPFX")
|
||||
}
|
||||
if version == 6 && softwareName == "" && f&messageBackupNexthops > 0 { // added in frr7.4
|
||||
if version == 6 && softwareName == "" && f&messageBackupNexthops > 0 { // added in frr7.4, frr7.5
|
||||
ss = append(ss, "BACKUP_NEXTHOPS")
|
||||
} else if version > 4 && f&MessageLabel > 0 {
|
||||
ss = append(ss, "LABEL")
|
||||
@@ -1001,6 +1037,9 @@ func (f MessageFlag) string(version uint8, softwareName string) string {
|
||||
if version > 5 && f&messageTableID > 0 {
|
||||
ss = append(ss, "TABLEID")
|
||||
}
|
||||
if version == 6 && softwareName == "" && f&messageSRTE > 0 { // added in frr7.5
|
||||
ss = append(ss, "SRTE")
|
||||
}
|
||||
return strings.Join(ss, "|")
|
||||
}
|
||||
|
||||
@@ -1338,7 +1377,7 @@ func NewClient(network, address string, typ RouteType, version uint8, software s
|
||||
|
||||
// Start receive loop only when the first message successfully received.
|
||||
go func() {
|
||||
defer closeChannel(incoming)
|
||||
defer close(incoming)
|
||||
for {
|
||||
if m, err := receiveSingleMsg(); err != nil {
|
||||
return
|
||||
@@ -1407,7 +1446,16 @@ func (c *Client) SendHello() error {
|
||||
|
||||
// SendRouterIDAdd sends ROUTER_ID_ADD message to zebra daemon.
|
||||
func (c *Client) SendRouterIDAdd() error {
|
||||
return c.sendCommand(routerIDAdd, DefaultVrf, nil)
|
||||
bodies := make([]*routerIDUpdateBody, 0)
|
||||
for _, afi := range []afi{afiIP, afiIP6} {
|
||||
bodies = append(bodies, &routerIDUpdateBody{
|
||||
afi: afi,
|
||||
})
|
||||
}
|
||||
for _, body := range bodies {
|
||||
c.sendCommand(routerIDAdd, DefaultVrf, body)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendInterfaceAdd sends INTERFACE_ADD message to zebra daemon.
|
||||
@@ -1417,7 +1465,6 @@ func (c *Client) SendInterfaceAdd() error {
|
||||
|
||||
// SendRedistribute sends REDISTRIBUTE message to zebra daemon.
|
||||
func (c *Client) SendRedistribute(t RouteType, vrfID uint32) error {
|
||||
|
||||
if c.redistDefault != t {
|
||||
bodies := make([]*redistributeBody, 0)
|
||||
if c.Version <= 3 {
|
||||
@@ -1435,7 +1482,7 @@ func (c *Client) SendRedistribute(t RouteType, vrfID uint32) error {
|
||||
}
|
||||
|
||||
for _, body := range bodies {
|
||||
return c.sendCommand(redistributeAdd, vrfID, body)
|
||||
c.sendCommand(redistributeAdd, vrfID, body)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -1634,16 +1681,22 @@ func (b *unknownBody) string(version uint8, softwareName string) string {
|
||||
type helloBody struct {
|
||||
redistDefault RouteType
|
||||
instance uint16
|
||||
sessionID uint32 // frr7.4, frr7.5
|
||||
receiveNotify uint8
|
||||
synchronous uint8 // frr7.4, frr7.5
|
||||
}
|
||||
|
||||
// Ref: zread_hello in zebra/zserv.c of Quagga1.2&FRR3 (ZAPI3&4)
|
||||
// Ref: zread_hello in zebra/zapi_msg.c of FRR5 (ZAPI5)
|
||||
func (b *helloBody) decodeFromBytes(data []byte, version uint8, softwareName string) error {
|
||||
b.redistDefault = RouteType(data[0])
|
||||
if version >= 4 {
|
||||
if version > 3 { //frr
|
||||
b.instance = binary.BigEndian.Uint16(data[1:3])
|
||||
if version >= 5 {
|
||||
if version == 6 && softwareName == "" { // frr7.5
|
||||
b.sessionID = binary.BigEndian.Uint32(data[3:7])
|
||||
b.receiveNotify = data[7]
|
||||
b.synchronous = data[8]
|
||||
} else if version > 4 {
|
||||
b.receiveNotify = data[3]
|
||||
}
|
||||
}
|
||||
@@ -1656,14 +1709,20 @@ func (b *helloBody) serialize(version uint8, softwareName string) ([]byte, error
|
||||
return []byte{uint8(b.redistDefault)}, nil
|
||||
}
|
||||
var buf []byte
|
||||
if version == 4 {
|
||||
buf = make([]byte, 3)
|
||||
if version == 6 && softwareName == "" { // frr7.5
|
||||
buf = make([]byte, 9)
|
||||
} else if version > 4 {
|
||||
buf = make([]byte, 4)
|
||||
} else if version == 4 {
|
||||
buf = make([]byte, 3)
|
||||
}
|
||||
buf[0] = uint8(b.redistDefault)
|
||||
binary.BigEndian.PutUint16(buf[1:3], b.instance)
|
||||
if version > 4 {
|
||||
if version == 6 && softwareName == "" { // frr7.5
|
||||
binary.BigEndian.PutUint32(buf[3:7], b.sessionID)
|
||||
buf[7] = b.receiveNotify
|
||||
buf[8] = b.synchronous
|
||||
} else if version > 4 {
|
||||
buf[3] = b.receiveNotify
|
||||
}
|
||||
return buf, nil
|
||||
@@ -1870,6 +1929,7 @@ func (b *interfaceAddressUpdateBody) string(version uint8, softwareName string)
|
||||
type routerIDUpdateBody struct {
|
||||
length uint8
|
||||
prefix net.IP
|
||||
afi afi
|
||||
}
|
||||
|
||||
// Ref: zebra_router_id_update_read in lib/zclient.c of Quagga1.2&FRR3&FRR5 (ZAPI3&4&5)
|
||||
@@ -1885,7 +1945,12 @@ func (b *routerIDUpdateBody) decodeFromBytes(data []byte, version uint8, softwar
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ref: zclient_send_router_id_update in lib/zclient.c of FRR7.5
|
||||
func (b *routerIDUpdateBody) serialize(version uint8, softwareName string) ([]byte, error) {
|
||||
if version == 6 && softwareName == "" {
|
||||
//stream_putw(s, afi);
|
||||
return []byte{0x00, uint8(b.afi)}, nil
|
||||
}
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
@@ -1894,9 +1959,11 @@ func (b *routerIDUpdateBody) string(version uint8, softwareName string) string {
|
||||
}
|
||||
|
||||
const (
|
||||
zapiNexthopFlagOnlink uint8 = 0x01 // frr7.1, 7.2, 7.3, 7.4
|
||||
zapiNexthopFlagLabel uint8 = 0x02 // frr7.3, 7.4
|
||||
zapiNexthopFlagWeight uint8 = 0x04 // frr7.3, 7.4
|
||||
zapiNexthopFlagOnlink uint8 = 0x01 // frr7.1, 7.2, 7.3, 7.4, 7.5
|
||||
zapiNexthopFlagLabel uint8 = 0x02 // frr7.3, 7.4, 7.5
|
||||
zapiNexthopFlagWeight uint8 = 0x04 // frr7.3, 7.4, 7.5
|
||||
zapiNexthopFlagHasBackup uint8 = 0x08 // frr7.4, 7.5
|
||||
|
||||
)
|
||||
|
||||
// Flag for nexthop processing. It is gobgp's internal flag.
|
||||
@@ -1921,7 +1988,7 @@ func nexthopProcessFlagForIPRouteBody(version uint8, softwareName string, isDeco
|
||||
processFlag := (nexthopHasVrfID | nexthopHasType) // frr4, 5, 6, 7
|
||||
if version == 6 {
|
||||
switch softwareName {
|
||||
case "":
|
||||
case "", "frr7.3":
|
||||
processFlag |= (nexthopHasFlag | nexthopProcessIPToIPIFindex)
|
||||
case "frr7.2", "frr7.0":
|
||||
processFlag |= nexthopHasOnlink
|
||||
@@ -1942,6 +2009,9 @@ type Nexthop struct {
|
||||
MplsLabels []uint32
|
||||
weight uint32
|
||||
rmac [6]byte
|
||||
srteColor uint32
|
||||
backupNum uint8
|
||||
backupIndex []uint8
|
||||
}
|
||||
|
||||
func (n Nexthop) string() string {
|
||||
@@ -1994,6 +2064,9 @@ func (n Nexthop) encode(version uint8, softwareName string, processFlag nexthopP
|
||||
if n.weight > 0 {
|
||||
n.flags |= zapiNexthopFlagWeight
|
||||
}
|
||||
if n.backupNum > 0 {
|
||||
n.flags |= zapiNexthopFlagHasBackup
|
||||
}
|
||||
}
|
||||
if processFlag&nexthopHasFlag > 0 || processFlag&nexthopHasOnlink > 0 {
|
||||
// frr7.1, 7.2 has onlink, 7.3 has flag
|
||||
@@ -2051,6 +2124,20 @@ func (n Nexthop) encode(version uint8, softwareName string, processFlag nexthopP
|
||||
//frr: stream_put(s, &(api_nh->rmac), sizeof(struct ethaddr));
|
||||
buf = append(buf, n.rmac[:]...)
|
||||
}
|
||||
// added in frr7.5 (Color for Segment Routing TE.)
|
||||
if message&messageSRTE > 0 && (version == 6 && softwareName == "") {
|
||||
tmpbuf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(tmpbuf, uint32(n.srteColor))
|
||||
buf = append(buf, tmpbuf...) //frr: stream_putl(s, api_nh->srte_color);
|
||||
}
|
||||
if n.flags&zapiNexthopFlagHasBackup > 0 {
|
||||
tmpbuf := make([]byte, 1+1*n.backupNum)
|
||||
tmpbuf[0] = n.backupNum //frr: stream_putc(s, api_nh->backup_num);
|
||||
for i := uint8(0); i < n.backupNum; i++ {
|
||||
tmpbuf[i+1] = n.backupIndex[i]
|
||||
}
|
||||
buf = append(buf, tmpbuf...)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
@@ -2109,7 +2196,10 @@ func (n *Nexthop) decode(data []byte, version uint8, softwareName string, family
|
||||
n.blackholeType = data[offset] //frr: STREAM_GETC(s, api_nh->bh_type);
|
||||
offset++
|
||||
}
|
||||
if n.flags&zapiNexthopFlagLabel > 0 || message&MessageLabel > 0 {
|
||||
if n.flags&zapiNexthopFlagLabel > 0 || (message&MessageLabel > 0 &&
|
||||
(version == 5 || version == 6 &&
|
||||
(softwareName == "frr6" || softwareName == "frr7" ||
|
||||
softwareName == "frr7.2"))) {
|
||||
n.LabelNum = uint8(data[offset]) //frr: STREAM_GETC(s, api_nh->label_num);
|
||||
offset++
|
||||
if n.LabelNum > maxMplsLabel {
|
||||
@@ -2136,6 +2226,25 @@ func (n *Nexthop) decode(data []byte, version uint8, softwareName string, family
|
||||
copy(n.rmac[0:], data[offset:offset+6])
|
||||
offset += 6
|
||||
}
|
||||
// added in frr7.5 (Color for Segment Routing TE.)
|
||||
if message&messageSRTE > 0 && (version == 6 && softwareName == "") {
|
||||
//STREAM_GETL(s, api_nh->srte_color);
|
||||
n.srteColor = binary.BigEndian.Uint32(data[offset:])
|
||||
offset += 4
|
||||
}
|
||||
// added in frr7.4 (Index of backup nexthop)
|
||||
if n.flags&zapiNexthopFlagHasBackup > 0 {
|
||||
n.backupNum = data[offset] //frr: STREAM_GETC(s, api_nh->backup_num);
|
||||
offset++
|
||||
if n.backupNum > 0 {
|
||||
n.backupIndex = make([]uint8, n.backupNum)
|
||||
for i := uint8(0); i < n.backupNum; i++ {
|
||||
//frr STREAM_GETC(s, api_nh->backup_idx[i]);
|
||||
n.backupIndex[i] = data[offset]
|
||||
offset++
|
||||
}
|
||||
}
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
@@ -2186,6 +2295,7 @@ type IPRouteBody struct {
|
||||
Mtu uint32
|
||||
tag uint32
|
||||
tableID uint32
|
||||
srteColor uint32
|
||||
API APIType // API is referred in zclient_test
|
||||
}
|
||||
|
||||
@@ -2261,13 +2371,25 @@ func (b *IPRouteBody) IsWithdraw(version uint8, softwareName string) bool {
|
||||
func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, error) {
|
||||
var buf []byte
|
||||
numNexthop := len(b.Nexthops)
|
||||
if version <= 3 {
|
||||
buf = make([]byte, 5)
|
||||
} else if version == 4 {
|
||||
buf = make([]byte, 10)
|
||||
} else { // version >= 5
|
||||
buf = make([]byte, 9) //type(1)+instance(2)+flags(4)+message(1)+safi(1)
|
||||
|
||||
bufInitSize := 12
|
||||
switch version {
|
||||
case 2, 3:
|
||||
bufInitSize = 5
|
||||
case 4:
|
||||
bufInitSize = 10
|
||||
case 5:
|
||||
bufInitSize = 9 //type(1)+instance(2)+flags(4)+message(1)+safi(1)
|
||||
case 6:
|
||||
switch softwareName {
|
||||
case "frr6", "frr7", "frr7.2", "frr7.3":
|
||||
bufInitSize = 9 //type(1)+instance(2)+flags(4)+message(1)+safi(1)
|
||||
default:
|
||||
bufInitSize = 12 //type(1)+instance(2)+flags(4)+message(4)+safi(1)
|
||||
}
|
||||
}
|
||||
buf = make([]byte, bufInitSize)
|
||||
|
||||
buf[0] = uint8(b.Type.toEach(version, softwareName)) //frr: stream_putc(s, api->type);
|
||||
if version < 4 {
|
||||
buf[1] = uint8(b.Flags)
|
||||
@@ -2278,27 +2400,33 @@ func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, err
|
||||
binary.BigEndian.PutUint16(buf[1:3], uint16(b.instance))
|
||||
//frr: stream_putl(s, api->flags);
|
||||
binary.BigEndian.PutUint32(buf[3:7], uint32(b.Flags))
|
||||
//frr: stream_putc(s, api->message);
|
||||
buf[7] = uint8(b.Message)
|
||||
if version == 4 {
|
||||
binary.BigEndian.PutUint16(buf[8:10], uint16(b.Safi))
|
||||
} else { // version >= 5
|
||||
//frr: stream_putc(s, api->safi);
|
||||
buf[8] = uint8(b.Safi)
|
||||
|
||||
// only zapi version 5 (frr4.0.x) have evpn routes
|
||||
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
|
||||
// size of struct ethaddr is 6 octets defined by ETH_ALEN
|
||||
buf = append(buf, b.Nexthops[numNexthop-1].rmac[:6]...)
|
||||
if version == 6 && softwareName == "" {
|
||||
//frr7.5: stream_putl(s, api->message);
|
||||
binary.BigEndian.PutUint32(buf[7:11], uint32(b.Message))
|
||||
buf[11] = uint8(b.Safi)
|
||||
} else {
|
||||
//before frr7.4: stream_putc(s, api->message);
|
||||
buf[7] = uint8(b.Message)
|
||||
if version > 4 {
|
||||
//frr: stream_putc(s, api->safi);
|
||||
buf[8] = uint8(b.Safi)
|
||||
} else { // version 2,3 and 4 (quagga, frr3)
|
||||
binary.BigEndian.PutUint16(buf[8:10], uint16(b.Safi))
|
||||
}
|
||||
|
||||
if b.Prefix.Family == syscall.AF_UNSPEC {
|
||||
b.Prefix.Family = familyFromPrefix(b.Prefix.Prefix)
|
||||
}
|
||||
//frr: stream_putc(s, api->prefix.family);
|
||||
buf = append(buf, b.Prefix.Family)
|
||||
}
|
||||
}
|
||||
// only zapi version 5 (frr4.0.x) have evpn routes
|
||||
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
|
||||
// size of struct ethaddr is 6 octets defined by ETH_ALEN
|
||||
buf = append(buf, b.Nexthops[numNexthop-1].rmac[:6]...)
|
||||
}
|
||||
if version > 4 { // version 5, 6 (after frr4)
|
||||
if b.Prefix.Family == syscall.AF_UNSPEC {
|
||||
b.Prefix.Family = familyFromPrefix(b.Prefix.Prefix)
|
||||
}
|
||||
//frr: stream_putc(s, api->prefix.family);
|
||||
buf = append(buf, b.Prefix.Family)
|
||||
}
|
||||
byteLen := (int(b.Prefix.PrefixLen) + 7) / 8
|
||||
buf = append(buf, b.Prefix.PrefixLen) //frr: stream_putc(s, api->prefix.prefixlen);
|
||||
//frr: stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
|
||||
@@ -2329,7 +2457,8 @@ func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, err
|
||||
buf = append(buf, nexthop.encode(version, softwareName, processFlag, b.Message, b.Flags)...)
|
||||
}
|
||||
}
|
||||
if b.Message&messageBackupNexthops > 0 { // added in frr7.4
|
||||
// MESSAGE_BACKUP_NEXTHOPS is added in frr7.4
|
||||
if version == 6 && softwareName == "" && b.Message&messageBackupNexthops > 0 {
|
||||
tmpbuf := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(tmpbuf, uint16(len(b.backupNexthops)))
|
||||
buf = append(buf, tmpbuf...) //frr: stream_putw(s, api->nexthop_num);
|
||||
@@ -2428,17 +2557,23 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
|
||||
b.Flags = Flag(binary.BigEndian.Uint32(data[3:7]))
|
||||
data = data[7:]
|
||||
}
|
||||
|
||||
b.Message = MessageFlag(data[0]) //frr: STREAM_GETC(s, api->message);
|
||||
if version == 6 && softwareName == "" {
|
||||
//frr7.5: STREAM_GETL(s, api->message);
|
||||
b.Message = MessageFlag(binary.BigEndian.Uint32(data[0:4]))
|
||||
data = data[4:]
|
||||
} else {
|
||||
b.Message = MessageFlag(data[0]) //frr: STREAM_GETC(s, api->message);
|
||||
data = data[1:]
|
||||
}
|
||||
b.Safi = Safi(SafiUnicast)
|
||||
b.Prefix.Family = b.API.addressFamily(version) // return AF_UNSPEC if version > 4
|
||||
var evpnNexthop Nexthop
|
||||
if version > 4 {
|
||||
b.Safi = Safi(data[1]) //frr: STREAM_GETC(s, api->safi);
|
||||
b.Safi = Safi(data[0]) //frr: STREAM_GETC(s, api->safi);
|
||||
if b.Safi > safiMax { //frr5 and later work, ToDo: fix for older version
|
||||
return fmt.Errorf("unknown safi type: %d in version: %d (%s)", b.Type, version, softwareName)
|
||||
}
|
||||
data = data[2:]
|
||||
data = data[1:]
|
||||
|
||||
// zapi version 5 only
|
||||
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
|
||||
@@ -2448,6 +2583,7 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
|
||||
}
|
||||
|
||||
b.Prefix.Family = data[0] //frr: STREAM_GETC(s, api->prefix.family);
|
||||
data = data[1:]
|
||||
}
|
||||
|
||||
addrByteLen, err := addressByteLength(b.Prefix.Family)
|
||||
@@ -2457,11 +2593,11 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
|
||||
|
||||
addrBitLen := uint8(addrByteLen * 8)
|
||||
|
||||
b.Prefix.PrefixLen = data[1] //frr: STREAM_GETC(s, api->prefix.prefixlen);
|
||||
b.Prefix.PrefixLen = data[0] //frr: STREAM_GETC(s, api->prefix.prefixlen);
|
||||
if b.Prefix.PrefixLen > addrBitLen {
|
||||
return fmt.Errorf("prefix length %d is greater than %d", b.Prefix.PrefixLen, addrBitLen)
|
||||
}
|
||||
data = data[2:]
|
||||
data = data[1:]
|
||||
pos := 0
|
||||
rest := len(data)
|
||||
|
||||
@@ -2474,6 +2610,7 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
|
||||
copy(buf, data[pos:pos+byteLen])
|
||||
b.Prefix.Prefix = ipFromFamily(b.Prefix.Family, buf)
|
||||
pos += byteLen
|
||||
|
||||
if version > 3 && b.Message&messageSRCPFX.ToEach(version) > 0 {
|
||||
if pos+1 > rest {
|
||||
return fmt.Errorf("MessageSRCPFX message length invalid pos:%d rest:%d", pos, rest)
|
||||
@@ -2496,21 +2633,28 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
|
||||
}
|
||||
|
||||
b.Nexthops = []Nexthop{}
|
||||
offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
if b.Message&MessageNexthop.ToEach(version) > 0 {
|
||||
offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pos += offset
|
||||
}
|
||||
pos += offset
|
||||
|
||||
b.backupNexthops = []Nexthop{} // backupNexthops is added in frr7.4
|
||||
offset, err = b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, true)
|
||||
if err != nil {
|
||||
return err
|
||||
if b.Message&messageBackupNexthops.ToEach(version) > 0 {
|
||||
offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pos += offset
|
||||
}
|
||||
pos += offset
|
||||
|
||||
// version 5 only, In version 6, EvpnRoute is processed in MessageNexthop
|
||||
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
|
||||
b.Nexthops = append(b.Nexthops, evpnNexthop)
|
||||
}
|
||||
|
||||
if version < 5 && b.Message&messageIFIndex > 0 { // version 4, 3, 2
|
||||
if pos+1 > rest {
|
||||
return fmt.Errorf("MessageIFIndex message length invalid pos:%d rest:%d", pos, rest)
|
||||
@@ -2792,17 +2936,27 @@ func (b *NexthopRegisterBody) string(version uint8, softwareName string) string
|
||||
// NexthopUpdateBody uses same data structure as IPRoute (zapi_route) after frr4 (Zapi5)
|
||||
type NexthopUpdateBody IPRouteBody
|
||||
|
||||
// Ref: send_client in zebra/zebra_rnh.c of Quagga1.2&FRR3&FRR5(ZAPI3&4$5)
|
||||
// Ref: send_client in zebra/zebra_rnh.c of Quagga1.2&FRR3&FRR5(ZAPI3&4$5) and befre FRR7.4
|
||||
// Ref: zebra_send_rnh_update zebra/zebra_rnh.c of FRR7.5
|
||||
func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byte, error) {
|
||||
var buf []byte
|
||||
offset := 0
|
||||
if version == 6 && softwareName == "" { // after frr7.5
|
||||
buf = make([]byte, 7)
|
||||
binary.BigEndian.PutUint32(buf, uint32(b.Message))
|
||||
offset += 4
|
||||
} else { // before frr7.4
|
||||
buf = make([]byte, 3)
|
||||
}
|
||||
|
||||
// Address Family (2 bytes)
|
||||
buf := make([]byte, 3)
|
||||
binary.BigEndian.PutUint16(buf, uint16(b.Prefix.Family))
|
||||
binary.BigEndian.PutUint16(buf[offset:], uint16(b.Prefix.Family))
|
||||
addrByteLen, err := addressByteLength(b.Prefix.Family)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf[2] = byte(addrByteLen * 8)
|
||||
buf[offset+2] = byte(addrByteLen * 8)
|
||||
// Prefix Length (1 byte) + Prefix (variable)
|
||||
switch b.Prefix.Family {
|
||||
case syscall.AF_INET:
|
||||
@@ -2812,6 +2966,11 @@ func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byt
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid address family: %d", b.Prefix.Family)
|
||||
}
|
||||
if b.Message&messageSRTE > 0 { // frr 7.5
|
||||
tmpbuf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(tmpbuf, b.srteColor)
|
||||
buf = append(buf, tmpbuf...)
|
||||
}
|
||||
if version >= 5 {
|
||||
// Type (1 byte) (if version>=5)
|
||||
// instance (2 bytes) (if version>=5)
|
||||
@@ -2837,6 +2996,11 @@ func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byt
|
||||
// Ref: bgp_parse_nexthop_update in bgpd/bgp_nht.c of Quagga1.2&FRR3 (ZAPI3&4)
|
||||
// Ref: zapi_nexthop_update_decode in lib/zclient.c of FRR5.x (ZAPI5)
|
||||
func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, softwareName string) error {
|
||||
if version == 6 && softwareName == "" { // frr7.5
|
||||
//frr7.5: STREAM_GETL(s, nhr->message);
|
||||
b.Message = MessageFlag(binary.BigEndian.Uint32(data[0:4]))
|
||||
data = data[4:]
|
||||
}
|
||||
// Address Family (2 bytes)
|
||||
prefixFamily := binary.BigEndian.Uint16(data[0:2])
|
||||
b.Prefix.Family = uint8(prefixFamily)
|
||||
@@ -2851,6 +3015,11 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
|
||||
b.Prefix.Prefix = ipFromFamily(b.Prefix.Family, data[offset:offset+addrByteLen])
|
||||
offset += addrByteLen
|
||||
|
||||
if b.Message&messageSRTE > 0 { // frr 7.5
|
||||
b.srteColor = binary.BigEndian.Uint32(data[offset : offset+4])
|
||||
offset += 4
|
||||
}
|
||||
|
||||
if version > 4 {
|
||||
b.Type = RouteType(data[offset])
|
||||
b.instance = binary.BigEndian.Uint16(data[offset+1 : offset+3])
|
||||
@@ -2876,7 +3045,7 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
|
||||
processFlag := nexthopProcessFlag(nexthopHasType)
|
||||
if version == 6 {
|
||||
switch softwareName {
|
||||
case "":
|
||||
case "", "frr7.3":
|
||||
processFlag |= (nexthopHasVrfID | nexthopHasFlag | nexthopProcessIPToIPIFindex)
|
||||
case "frr7.0", "frr7.2":
|
||||
processFlag |= (nexthopHasVrfID | nexthopProcessIPToIPIFindex)
|
||||
@@ -2885,20 +3054,20 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
|
||||
}
|
||||
} else if version == 5 {
|
||||
switch softwareName {
|
||||
case "frr5", "":
|
||||
case "":
|
||||
processFlag |= nexthopProcessIPToIPIFindex
|
||||
}
|
||||
} else if version < 4 { // quagga
|
||||
processFlag |= nexthopProcessIFnameToIFindex
|
||||
}
|
||||
|
||||
message := MessageFlag(0)
|
||||
// after frr7.3, MessageLabel is deleted
|
||||
if (version == 6 && !(softwareName == "frr7.3" || softwareName == "")) ||
|
||||
(version == 5 && (softwareName == "frr5" || softwareName == "")) {
|
||||
message |= MessageLabel
|
||||
(version == 5 && softwareName == "") {
|
||||
b.Message |= MessageLabel
|
||||
}
|
||||
|
||||
nexthopsByteLen, err := decodeNexthops(&b.Nexthops, data[offset:], version, softwareName, b.Prefix.Family, numNexthop, processFlag, message, Flag(0), nexthopType(0))
|
||||
nexthopsByteLen, err := decodeNexthops(&b.Nexthops, data[offset:], version, softwareName, b.Prefix.Family, numNexthop, processFlag, b.Message, Flag(0), nexthopType(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user