diff options
Diffstat (limited to 'table/path.go')
-rw-r--r-- | table/path.go | 203 |
1 files changed, 71 insertions, 132 deletions
diff --git a/table/path.go b/table/path.go index a5c08e8f..e7536f22 100644 --- a/table/path.go +++ b/table/path.go @@ -18,15 +18,16 @@ package table import ( "fmt" "github.com/osrg/gobgp/packet" - "github.com/osrg/gobgp/utils" + //"github.com/osrg/gobgp/utils" "net" + "reflect" ) type Path interface { String() string - getPathAttributeMap() *utils.OrderedMap - getPathAttribute(int) bgp.PathAttributeInterface - clone(forWithdrawal bool) Path + GetPathAttrs() []bgp.PathAttributeInterface + GetPathAttr(int) (int, bgp.PathAttributeInterface) + // clone(forWithdrawal bool) Path getRouteFamily() RouteFamily setSource(source *PeerInfo) getSource() *PeerInfo @@ -49,32 +50,20 @@ type PathDefault struct { sourceVerNum int withdraw bool nlri bgp.AddrPrefixInterface - pattrMap *utils.OrderedMap + pathAttrs []bgp.PathAttributeInterface medSetByTargetNeighbor bool } -func NewPathDefault(rf RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInterface, sourceVerNum int, nexthop net.IP, - isWithdraw bool, pattr *utils.OrderedMap, medSetByTargetNeighbor bool) *PathDefault { +func NewPathDefault(rf RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInterface, sourceVerNum int, nexthop net.IP, isWithdraw bool, pattrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool) *PathDefault { - if !isWithdraw && (pattr == nil || nexthop == nil) { + if !isWithdraw && pattrs == nil { logger.Error("Need to provide nexthop and patattrs for path that is not a withdraw.") return nil } path := &PathDefault{} path.routeFamily = rf - path.pattrMap = utils.NewOrderedMap() - if pattr != nil { - keyList := pattr.KeyLists() - for key := keyList.Front(); key != nil; key = key.Next() { - key := key.Value - val := pattr.Get(key) - e := path.pattrMap.Append(key, val) - if e != nil { - logger.Error(e) - } - } - } + path.pathAttrs = pattrs path.nlri = nlri path.source = source path.nexthop = nexthop @@ -132,46 +121,53 @@ func (pd *PathDefault) getMedSetByTargetNeighbor() bool { return pd.medSetByTargetNeighbor } -//Copy the entity -func (pd *PathDefault) getPathAttributeMap() *utils.OrderedMap { - cpPattr := utils.NewOrderedMap() - keyList := pd.pattrMap.KeyLists() - for key := keyList.Front(); key != nil; key = key.Next() { - key := key.Value - val := pd.pattrMap.Get(key) - e := cpPattr.Append(key, val) - if e != nil { - logger.Error(e) +func (pd *PathDefault) GetPathAttrs() []bgp.PathAttributeInterface { + return pd.pathAttrs +} + +func (pd *PathDefault) GetPathAttr(pattrType int) (int, bgp.PathAttributeInterface) { + attrMap := [bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR + 1]reflect.Type{} + attrMap[bgp.BGP_ATTR_TYPE_ORIGIN] = reflect.TypeOf(&bgp.PathAttributeOrigin{}) + attrMap[bgp.BGP_ATTR_TYPE_AS_PATH] = reflect.TypeOf(&bgp.PathAttributeAsPath{}) + attrMap[bgp.BGP_ATTR_TYPE_NEXT_HOP] = reflect.TypeOf(&bgp.PathAttributeNextHop{}) + attrMap[bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC] = reflect.TypeOf(&bgp.PathAttributeMultiExitDisc{}) + attrMap[bgp.BGP_ATTR_TYPE_LOCAL_PREF] = reflect.TypeOf(&bgp.PathAttributeLocalPref{}) + attrMap[bgp.BGP_ATTR_TYPE_ATOMIC_AGGREGATE] = reflect.TypeOf(&bgp.PathAttributeAtomicAggregate{}) + attrMap[bgp.BGP_ATTR_TYPE_AGGREGATOR] = reflect.TypeOf(&bgp.PathAttributeAggregator{}) + attrMap[bgp.BGP_ATTR_TYPE_COMMUNITIES] = reflect.TypeOf(&bgp.PathAttributeCommunities{}) + attrMap[bgp.BGP_ATTR_TYPE_ORIGINATOR_ID] = reflect.TypeOf(&bgp.PathAttributeOriginatorId{}) + attrMap[bgp.BGP_ATTR_TYPE_CLUSTER_LIST] = reflect.TypeOf(&bgp.PathAttributeClusterList{}) + attrMap[bgp.BGP_ATTR_TYPE_MP_REACH_NLRI] = reflect.TypeOf(&bgp.PathAttributeMpReachNLRI{}) + attrMap[bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI] = reflect.TypeOf(&bgp.PathAttributeMpUnreachNLRI{}) + attrMap[bgp.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = reflect.TypeOf(&bgp.PathAttributeExtendedCommunities{}) + attrMap[bgp.BGP_ATTR_TYPE_AS4_PATH] = reflect.TypeOf(&bgp.PathAttributeAs4Path{}) + attrMap[bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR] = reflect.TypeOf(&bgp.PathAttributeAs4Aggregator{}) + + t := attrMap[pattrType] + for i, p := range pd.pathAttrs { + if t == reflect.TypeOf(p) { + return i, p } } - return cpPattr -} - -func (pd *PathDefault) getPathAttribute(pattrType int) bgp.PathAttributeInterface { - attr := pd.pattrMap.Get(pattrType) - if attr == nil { - logger.Debugf("Attribute Type %s is not found", AttributeType(pattrType)) - return nil - } - return attr.(bgp.PathAttributeInterface) -} - -func (pi *PathDefault) clone(forWithdrawal bool) Path { - pathAttrs := utils.NewOrderedMap() - if !forWithdrawal { - pathAttrs = pi.getPathAttributeMap() - } - def := NewPathDefault(pi.getRouteFamily(), pi.getSource(), pi.GetNlri(), pi.getSourceVerNum(), - pi.getNexthop(), forWithdrawal, pathAttrs, pi.getMedSetByTargetNeighbor()) - switch pi.getRouteFamily() { - case RF_IPv4_UC: - return &IPv4Path{PathDefault: def} - case RF_IPv6_UC: - return &IPv6Path{PathDefault: def} - default: - return def - } -} + return -1, nil +} + +// func (pi *PathDefault) clone(forWithdrawal bool) Path { +// pathAttrs := utils.NewOrderedMap() +// if !forWithdrawal { +// pathAttrs = pi.getPathAttributeMap() +// } +// def := NewPathDefault(pi.getRouteFamily(), pi.getSource(), pi.GetNlri(), pi.getSourceVerNum(), +// pi.getNexthop(), forWithdrawal, pathAttrs, pi.getMedSetByTargetNeighbor()) +// switch pi.getRouteFamily() { +// case RF_IPv4_UC: +// return &IPv4Path{PathDefault: def} +// case RF_IPv6_UC: +// return &IPv6Path{PathDefault: def} +// default: +// return def +// } +//} // return Path's string representation func (pi *PathDefault) String() string { @@ -179,7 +175,7 @@ func (pi *PathDefault) String() string { str = str + fmt.Sprintf(" NLRI: %s, ", pi.getPrefix().String()) str = str + fmt.Sprintf(" nexthop: %s, ", pi.getNexthop().String()) str = str + fmt.Sprintf(" withdraw: %s, ", pi.isWithdraw()) - str = str + fmt.Sprintf(" path attributes: %s, ", pi.getPathAttributeMap()) + //str = str + fmt.Sprintf(" path attributes: %s, ", pi.getPathAttributeMap()) return str } @@ -194,57 +190,11 @@ func (pi *PathDefault) getPrefix() net.IP { return nil } -func createPathAttributeMap(pathAttributes []bgp.PathAttributeInterface) *utils.OrderedMap { - - pathAttrMap := utils.NewOrderedMap() - for _, attr := range pathAttributes { - var err error - switch a := attr.(type) { - case *bgp.PathAttributeOrigin: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_ORIGIN, a) - case *bgp.PathAttributeAsPath: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_AS_PATH, a) - case *bgp.PathAttributeNextHop: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_NEXT_HOP, a) - case *bgp.PathAttributeMultiExitDisc: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC, a) - case *bgp.PathAttributeLocalPref: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_LOCAL_PREF, a) - case *bgp.PathAttributeAtomicAggregate: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_ATOMIC_AGGREGATE, a) - case *bgp.PathAttributeAggregator: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_AGGREGATOR, a) - case *bgp.PathAttributeCommunities: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_COMMUNITIES, a) - case *bgp.PathAttributeOriginatorId: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_ORIGINATOR_ID, a) - case *bgp.PathAttributeClusterList: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_CLUSTER_LIST, a) - case *bgp.PathAttributeMpReachNLRI: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI, a) - case *bgp.PathAttributeMpUnreachNLRI: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI, a) - case *bgp.PathAttributeExtendedCommunities: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES, a) - case *bgp.PathAttributeAs4Path: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_AS4_PATH, a) - case *bgp.PathAttributeAs4Aggregator: - err = pathAttrMap.Append(bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR, a) - } - if err != nil { - return nil - } - } - return pathAttrMap -} - // create Path object based on route family -func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, - pathAttributes []bgp.PathAttributeInterface, isWithdraw bool) Path { +func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, attrs []bgp.PathAttributeInterface, isWithdraw bool) Path { rf := RouteFamily(int(nlri.AFI())<<16 | int(nlri.SAFI())) logger.Debugf("afi: %d, safi: %d ", int(nlri.AFI()), nlri.SAFI()) - pathAttrMap := createPathAttributeMap(pathAttributes) var path Path var sourceVerNum int = 1 @@ -255,27 +205,10 @@ func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, switch rf { case RF_IPv4_UC: logger.Debugf("RouteFamily : %s", RF_IPv4_UC.String()) - var nexthop net.IP - - if !isWithdraw { - nexthop_attr := pathAttrMap.Get(bgp.BGP_ATTR_TYPE_NEXT_HOP).(*bgp.PathAttributeNextHop) - nexthop = nexthop_attr.Value - } else { - nexthop = nil - } - - path = NewIPv4Path(source, nlri, sourceVerNum, nexthop, isWithdraw, pathAttrMap, false) + path = NewIPv4Path(source, nlri, sourceVerNum, isWithdraw, attrs, false) case RF_IPv6_UC: logger.Debugf("RouteFamily : %s", RF_IPv6_UC.String()) - var nexthop net.IP - - if !isWithdraw { - mpattr := pathAttrMap.Get(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI).(*bgp.PathAttributeMpReachNLRI) - nexthop = mpattr.Nexthop - } else { - nexthop = nil - } - path = NewIPv6Path(source, nlri, sourceVerNum, nexthop, isWithdraw, pathAttrMap, false) + path = NewIPv6Path(source, nlri, sourceVerNum, isWithdraw, attrs, false) } return path } @@ -287,10 +220,13 @@ type IPv4Path struct { *PathDefault } -func NewIPv4Path(source *PeerInfo, nlri bgp.AddrPrefixInterface, sourceVerNum int, nexthop net.IP, - isWithdraw bool, pattr *utils.OrderedMap, medSetByTargetNeighbor bool) *IPv4Path { +func NewIPv4Path(source *PeerInfo, nlri bgp.AddrPrefixInterface, sourceVerNum int, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool) *IPv4Path { ipv4Path := &IPv4Path{} - ipv4Path.PathDefault = NewPathDefault(RF_IPv4_UC, source, nlri, sourceVerNum, nexthop, isWithdraw, pattr, medSetByTargetNeighbor) + ipv4Path.PathDefault = NewPathDefault(RF_IPv4_UC, source, nlri, sourceVerNum, nil, isWithdraw, attrs, medSetByTargetNeighbor) + if !isWithdraw { + _, nexthop_attr := ipv4Path.GetPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) + ipv4Path.nexthop = nexthop_attr.(*bgp.PathAttributeNextHop).Value + } return ipv4Path } @@ -305,10 +241,13 @@ type IPv6Path struct { *PathDefault } -func NewIPv6Path(source *PeerInfo, nlri bgp.AddrPrefixInterface, sourceVerNum int, nexthop net.IP, - isWithdraw bool, pattr *utils.OrderedMap, medSetByTargetNeighbor bool) *IPv6Path { +func NewIPv6Path(source *PeerInfo, nlri bgp.AddrPrefixInterface, sourceVerNum int, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool) *IPv6Path { ipv6Path := &IPv6Path{} - ipv6Path.PathDefault = NewPathDefault(RF_IPv6_UC, source, nlri, sourceVerNum, nexthop, isWithdraw, pattr, medSetByTargetNeighbor) + ipv6Path.PathDefault = NewPathDefault(RF_IPv6_UC, source, nlri, sourceVerNum, nil, isWithdraw, attrs, medSetByTargetNeighbor) + if !isWithdraw { + _, mpattr := ipv6Path.GetPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) + ipv6Path.nexthop = mpattr.(*bgp.PathAttributeMpReachNLRI).Nexthop + } return ipv6Path } @@ -331,6 +270,6 @@ func (ipv6p *IPv6Path) String() string { str = str + fmt.Sprintf(" NLRI: %s, ", ipv6p.getPrefix().String()) str = str + fmt.Sprintf(" nexthop: %s, ", ipv6p.getNexthop().String()) str = str + fmt.Sprintf(" withdraw: %s, ", ipv6p.isWithdraw()) - str = str + fmt.Sprintf(" path attributes: %s, ", ipv6p.getPathAttributeMap()) + //str = str + fmt.Sprintf(" path attributes: %s, ", ipv6p.getPathAttributeMap()) return str } |