update gobgp pkg
This commit is contained in:
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)
|
||||
|
||||
Reference in New Issue
Block a user