summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2018-02-27 09:49:35 +0900
committerIWASE Yusuke <iwase.yusuke0@gmail.com>2018-04-03 09:16:41 +0900
commit264bd0ca126bf721687764332a01315d56e5b671 (patch)
tree05a0eb911e99fcba2a621fde34f6fc749f130d1d
parenta25522edddf05653bef26c5ff220f34f7354791f (diff)
packet/bgp: Getter functions for AS segment
This patch adds getter functions for the segment type and AS list of each segment without using type assertion. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r--gobgp/cmd/neighbor.go8
-rw-r--r--packet/bgp/bgp.go22
-rw-r--r--packet/bgp/validate.go17
-rw-r--r--server/fsm.go6
-rw-r--r--server/rpki.go9
-rw-r--r--table/destination.go15
-rw-r--r--table/message.go48
-rw-r--r--table/path.go85
8 files changed, 119 insertions, 91 deletions
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index 7414c17c..edcb11bf 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -565,8 +565,8 @@ func checkOriginAsWasNotShown(p *table.Path, shownAs map[uint32]struct{}) bool {
if len(asPath) == 0 {
return false
}
- aslist := asPath[len(asPath)-1].(*bgp.As4PathParam).AS
- origin := aslist[len(aslist)-1]
+ asList := asPath[len(asPath)-1].GetAS()
+ origin := asList[len(asList)-1]
if _, ok := shownAs[origin]; ok {
return false
@@ -585,8 +585,8 @@ func showValidationInfo(p *table.Path, shownAs map[uint32]struct{}) error {
status := p.Validation().Status
reason := p.Validation().Reason
- aslist := asPath[len(asPath)-1].(*bgp.As4PathParam).AS
- origin := aslist[len(aslist)-1]
+ asList := asPath[len(asPath)-1].GetAS()
+ origin := asList[len(asList)-1]
fmt.Printf("Target Prefix: %s, AS: %d\n", p.GetNlri().String(), origin)
fmt.Printf(" This route is %s", status)
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index 2fea8b44..ef2e3e20 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -5213,6 +5213,8 @@ var asPathParamFormatMap = map[uint8]*AsPathParamFormat{
}
type AsPathParamInterface interface {
+ GetType() uint8
+ GetAS() []uint32
Serialize() ([]byte, error)
DecodeFromBytes([]byte) error
Len() int
@@ -5227,6 +5229,18 @@ type AsPathParam struct {
AS []uint16
}
+func (a *AsPathParam) GetType() uint8 {
+ return a.Type
+}
+
+func (a *AsPathParam) GetAS() []uint32 {
+ nums := make([]uint32, 0, len(a.AS))
+ for _, as := range a.AS {
+ nums = append(nums, uint32(as))
+ }
+ return nums
+}
+
func (a *AsPathParam) Serialize() ([]byte, error) {
buf := make([]byte, 2+len(a.AS)*2)
buf[0] = uint8(a.Type)
@@ -5314,6 +5328,14 @@ type As4PathParam struct {
AS []uint32
}
+func (a *As4PathParam) GetType() uint8 {
+ return a.Type
+}
+
+func (a *As4PathParam) GetAS() []uint32 {
+ return a.AS
+}
+
func (a *As4PathParam) Serialize() ([]byte, error) {
buf := make([]byte, 2+len(a.AS)*4)
buf[0] = a.Type
diff --git a/packet/bgp/validate.go b/packet/bgp/validate.go
index ecc67067..1b8f27c9 100644
--- a/packet/bgp/validate.go
+++ b/packet/bgp/validate.go
@@ -173,23 +173,16 @@ func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]BGPAddPathM
}
}
case *PathAttributeAsPath:
- getSegType := func(p AsPathParamInterface) uint8 {
- asParam, y := p.(*As4PathParam)
- if y {
- return asParam.Type
- } else {
- return p.(*AsPathParam).Type
- }
- }
if isEBGP {
if isConfed {
- if segType := getSegType(p.Value[0]); segType != BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
+ if segType := p.Value[0].GetType(); segType != BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
return false, NewMessageError(eCode, eSubCodeMalformedAspath, nil, fmt.Sprintf("segment type is not confederation seq (%d)", segType))
}
} else {
- for _, paramIf := range p.Value {
- segType := getSegType(paramIf)
- if segType == BGP_ASPATH_ATTR_TYPE_CONFED_SET || segType == BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
+ for _, param := range p.Value {
+ segType := param.GetType()
+ switch segType {
+ case BGP_ASPATH_ATTR_TYPE_CONFED_SET, BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
err := NewMessageErrorWithErrorHandling(
eCode, eSubCodeMalformedAspath, nil, getErrorHandlingFromPathAttribute(p.GetType()), nil, fmt.Sprintf("segment type confederation(%d) found", segType))
if err.(*MessageError).Stronger(strongestError) {
diff --git a/server/fsm.go b/server/fsm.go
index 2c2128cb..c121c85f 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -677,10 +677,10 @@ func getPathAttrFromBGPUpdate(m *bgp.BGPUpdate, typ bgp.BGPAttrType) bgp.PathAtt
return nil
}
-func hasOwnASLoop(ownAS uint32, limit int, aspath *bgp.PathAttributeAsPath) bool {
+func hasOwnASLoop(ownAS uint32, limit int, asPath *bgp.PathAttributeAsPath) bool {
cnt := 0
- for _, i := range aspath.Value {
- for _, as := range i.(*bgp.As4PathParam).AS {
+ for _, param := range asPath.Value {
+ for _, as := range param.GetAS() {
if as == ownAS {
cnt++
if cnt > limit {
diff --git a/server/rpki.go b/server/rpki.go
index 8f286930..75f25409 100644
--- a/server/rpki.go
+++ b/server/rpki.go
@@ -511,13 +511,14 @@ func ValidatePath(ownAs uint32, tree *radix.Tree, cidr string, asPath *bgp.PathA
if asPath == nil || len(asPath.Value) == 0 {
as = ownAs
} else {
- asParam := asPath.Value[len(asPath.Value)-1].(*bgp.As4PathParam)
- switch asParam.Type {
+ param := asPath.Value[len(asPath.Value)-1]
+ switch param.GetType() {
case bgp.BGP_ASPATH_ATTR_TYPE_SEQ:
- if len(asParam.AS) == 0 {
+ asList := param.GetAS()
+ if len(asList) == 0 {
as = ownAs
} else {
- as = asParam.AS[len(asParam.AS)-1]
+ as = asList[len(asList)-1]
}
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
as = ownAs
diff --git a/table/destination.go b/table/destination.go
index f9ed3509..fd32371d 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -861,17 +861,18 @@ func compareByMED(path1, path2 *Path) *Path {
isSameAS := func() bool {
firstAS := func(path *Path) uint32 {
- if aspath := path.GetAsPath(); aspath != nil {
- asPathParam := aspath.Value
- for i := 0; i < len(asPathParam); i++ {
- asPath := asPathParam[i].(*bgp.As4PathParam)
- if asPath.Num == 0 {
+ if asPath := path.GetAsPath(); asPath != nil {
+ for _, v := range asPath.Value {
+ segType := v.GetType()
+ asList := v.GetAS()
+ if len(asList) == 0 {
continue
}
- if asPath.Type == bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET || asPath.Type == bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
+ switch segType {
+ case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
continue
}
- return asPath.AS[0]
+ return asList[0]
}
}
return 0
diff --git a/table/message.go b/table/message.go
index 0909d08f..a7195ac6 100644
--- a/table/message.go
+++ b/table/message.go
@@ -45,9 +45,10 @@ func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
as2Params := make([]bgp.AsPathParamInterface, 0, len(asAttr.Value))
mkAs4 := false
for _, param := range asAttr.Value {
- as4Param := param.(*bgp.As4PathParam)
- as2Path := make([]uint16, 0, len(as4Param.AS))
- for _, as := range as4Param.AS {
+ segType := param.GetType()
+ asList := param.GetAS()
+ as2Path := make([]uint16, 0, len(asList))
+ for _, as := range asList {
if as > (1<<16)-1 {
mkAs4 = true
as2Path = append(as2Path, bgp.AS_TRANS)
@@ -55,15 +56,20 @@ func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
as2Path = append(as2Path, uint16(as))
}
}
- as2Params = append(as2Params, bgp.NewAsPathParam(as4Param.Type, as2Path))
+ as2Params = append(as2Params, bgp.NewAsPathParam(segType, as2Path))
// RFC 6793 4.2.2 Generating Updates
//
// Whenever the AS path information contains the AS_CONFED_SEQUENCE or
// AS_CONFED_SET path segment, the NEW BGP speaker MUST exclude such
// path segments from the AS4_PATH attribute being constructed.
- if as4Param.Type != bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ && as4Param.Type != bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET {
- as4Params = append(as4Params, as4Param)
+ switch segType {
+ case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET:
+ // pass
+ default:
+ if as4param, ok := param.(*bgp.As4PathParam); ok {
+ as4Params = append(as4Params, as4param)
+ }
}
}
msg.PathAttributes[idx] = bgp.NewPathAttributeAsPath(as2Params)
@@ -111,21 +117,20 @@ func UpdatePathAttrs4ByteAs(msg *bgp.BGPUpdate) error {
asLen := 0
asConfedLen := 0
- asParams := make([]*bgp.As4PathParam, 0, len(asAttr.Value))
+ asParams := make([]bgp.AsPathParamInterface, 0, len(asAttr.Value))
for _, param := range asAttr.Value {
asLen += param.ASLen()
- p := param.(*bgp.As4PathParam)
- switch p.Type {
+ switch param.GetType() {
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET:
- asConfedLen += 1
+ asConfedLen++
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
- asConfedLen += len(p.AS)
+ asConfedLen += len(param.GetAS())
}
- asParams = append(asParams, p)
+ asParams = append(asParams, param)
}
as4Len := 0
- as4Params := make([]*bgp.As4PathParam, 0, len(as4Attr.Value))
+ as4Params := make([]bgp.AsPathParamInterface, 0, len(as4Attr.Value))
if as4Attr != nil {
for _, p := range as4Attr.Value {
// RFC 6793 6. Error Handling
@@ -162,14 +167,14 @@ func UpdatePathAttrs4ByteAs(msg *bgp.BGPUpdate) error {
keepNum := asLen + asConfedLen - as4Len
- newParams := make([]*bgp.As4PathParam, 0, len(asAttr.Value))
+ newParams := make([]bgp.AsPathParamInterface, 0, len(asAttr.Value))
for _, param := range asParams {
if keepNum-param.ASLen() >= 0 {
newParams = append(newParams, param)
keepNum -= param.ASLen()
} else {
// only SEQ param reaches here
- newParams = append(newParams, bgp.NewAs4PathParam(param.Type, param.AS[:keepNum]))
+ newParams = append(newParams, bgp.NewAs4PathParam(param.GetType(), param.GetAS()[:keepNum]))
keepNum = 0
}
@@ -180,12 +185,15 @@ func UpdatePathAttrs4ByteAs(msg *bgp.BGPUpdate) error {
for _, param := range as4Params {
lastParam := newParams[len(newParams)-1]
- if param.Type == lastParam.Type && param.Type == bgp.BGP_ASPATH_ATTR_TYPE_SEQ {
- if len(lastParam.AS)+len(param.AS) > 255 {
- newParams[len(newParams)-1] = bgp.NewAs4PathParam(param.Type, append(lastParam.AS, param.AS[:255-len(lastParam.AS)]...))
- newParams = append(newParams, bgp.NewAs4PathParam(param.Type, param.AS[255-len(lastParam.AS):]))
+ lastParamAS := lastParam.GetAS()
+ paramType := param.GetType()
+ paramAS := param.GetAS()
+ if paramType == lastParam.GetType() && paramType == bgp.BGP_ASPATH_ATTR_TYPE_SEQ {
+ if len(lastParamAS)+len(paramAS) > 255 {
+ newParams[len(newParams)-1] = bgp.NewAs4PathParam(paramType, append(lastParamAS, paramAS[:255-len(lastParamAS)]...))
+ newParams = append(newParams, bgp.NewAs4PathParam(paramType, paramAS[255-len(lastParamAS):]))
} else {
- newParams[len(newParams)-1] = bgp.NewAs4PathParam(param.Type, append(lastParam.AS, param.AS...))
+ newParams[len(newParams)-1] = bgp.NewAs4PathParam(paramType, append(lastParamAS, paramAS...))
}
} else {
newParams = append(newParams, param)
diff --git a/table/path.go b/table/path.go
index a04e0d66..de60e615 100644
--- a/table/path.go
+++ b/table/path.go
@@ -196,10 +196,10 @@ func (path *Path) IsEOR() bool {
func cloneAsPath(asAttr *bgp.PathAttributeAsPath) *bgp.PathAttributeAsPath {
newASparams := make([]bgp.AsPathParamInterface, len(asAttr.Value))
for i, param := range asAttr.Value {
- asParam := param.(*bgp.As4PathParam)
- as := make([]uint32, len(asParam.AS))
- copy(as, asParam.AS)
- newASparams[i] = bgp.NewAs4PathParam(asParam.Type, as)
+ asList := param.GetAS()
+ as := make([]uint32, len(asList))
+ copy(as, asList)
+ newASparams[i] = bgp.NewAs4PathParam(param.GetType(), as)
}
return bgp.NewPathAttributeAsPath(newASparams)
}
@@ -439,11 +439,11 @@ func (path *Path) GetSourceAs() uint32 {
if len(asPathParam) == 0 {
return 0
}
- asPath := asPathParam[len(asPathParam)-1].(*bgp.As4PathParam)
- if asPath.Num == 0 {
+ asList := asPathParam[len(asPathParam)-1].GetAS()
+ if len(asList) == 0 {
return 0
}
- return asPath.AS[asPath.Num-1]
+ return asList[len(asList)-1]
}
return 0
}
@@ -631,14 +631,15 @@ func (path *Path) GetAsPathLen() int {
func (path *Path) GetAsString() string {
s := bytes.NewBuffer(make([]byte, 0, 64))
if aspath := path.GetAsPath(); aspath != nil {
- for i, paramIf := range aspath.Value {
- segment := paramIf.(*bgp.As4PathParam)
+ for i, param := range aspath.Value {
+ segType := param.GetType()
+ asList := param.GetAS()
if i != 0 {
s.WriteString(" ")
}
sep := " "
- switch segment.Type {
+ switch segType {
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
s.WriteString("(")
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET:
@@ -648,13 +649,13 @@ func (path *Path) GetAsString() string {
s.WriteString("{")
sep = ","
}
- for j, as := range segment.AS {
+ for j, as := range asList {
s.WriteString(fmt.Sprintf("%d", as))
- if j != len(segment.AS)-1 {
+ if j != len(asList)-1 {
s.WriteString(sep)
}
}
- switch segment.Type {
+ switch segType {
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
s.WriteString(")")
case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET:
@@ -668,26 +669,26 @@ func (path *Path) GetAsString() string {
}
func (path *Path) GetAsList() []uint32 {
- return path.getAsListofSpecificType(true, true)
+ return path.getAsListOfSpecificType(true, true)
}
func (path *Path) GetAsSeqList() []uint32 {
- return path.getAsListofSpecificType(true, false)
+ return path.getAsListOfSpecificType(true, false)
}
-func (path *Path) getAsListofSpecificType(getAsSeq, getAsSet bool) []uint32 {
+func (path *Path) getAsListOfSpecificType(getAsSeq, getAsSet bool) []uint32 {
asList := []uint32{}
if aspath := path.GetAsPath(); aspath != nil {
- for _, paramIf := range aspath.Value {
- segment := paramIf.(*bgp.As4PathParam)
- if getAsSeq && segment.Type == bgp.BGP_ASPATH_ATTR_TYPE_SEQ {
- asList = append(asList, segment.AS...)
+ for _, param := range aspath.Value {
+ segType := param.GetType()
+ if getAsSeq && segType == bgp.BGP_ASPATH_ATTR_TYPE_SEQ {
+ asList = append(asList, param.GetAS()...)
continue
}
- if getAsSet && segment.Type == bgp.BGP_ASPATH_ATTR_TYPE_SET {
- asList = append(asList, segment.AS...)
+ if getAsSet && segType == bgp.BGP_ASPATH_ATTR_TYPE_SET {
+ asList = append(asList, param.GetAS()...)
} else {
asList = append(asList, 0)
}
@@ -757,7 +758,7 @@ func (path *Path) PrependAsn(asn uint32, repeat uint8, confed bool) {
original := path.GetAsPath()
asns := make([]uint32, repeat)
- for i, _ := range asns {
+ for i := range asns {
asns[i] = asn
}
@@ -769,13 +770,14 @@ func (path *Path) PrependAsn(asn uint32, repeat uint8, confed bool) {
}
if len(asPath.Value) > 0 {
- fst := asPath.Value[0].(*bgp.As4PathParam)
- if fst.Type == segType {
- if len(fst.AS)+int(repeat) > 255 {
- repeat = uint8(255 - len(fst.AS))
+ param := asPath.Value[0]
+ asList := param.GetAS()
+ if param.GetType() == segType {
+ if int(repeat)+len(asList) > 255 {
+ repeat = uint8(255 - len(asList))
}
- fst.AS = append(asns[:int(repeat)], fst.AS...)
- fst.Num += repeat
+ newAsList := append(asns[:int(repeat)], asList...)
+ asPath.Value[0] = bgp.NewAs4PathParam(segType, newAsList)
asns = asns[int(repeat):]
}
}
@@ -800,9 +802,9 @@ func (path *Path) RemovePrivateAS(localAS uint32, option config.RemovePrivateAsO
case config.REMOVE_PRIVATE_AS_OPTION_ALL, config.REMOVE_PRIVATE_AS_OPTION_REPLACE:
newASParams := make([]bgp.AsPathParamInterface, 0, len(original.Value))
for _, param := range original.Value {
- asParam := param.(*bgp.As4PathParam)
- newASParam := make([]uint32, 0, len(asParam.AS))
- for _, as := range asParam.AS {
+ asList := param.GetAS()
+ newASParam := make([]uint32, 0, len(asList))
+ for _, as := range asList {
if isPrivateAS(as) {
if option == config.REMOVE_PRIVATE_AS_OPTION_REPLACE {
newASParam = append(newASParam, localAS)
@@ -812,7 +814,7 @@ func (path *Path) RemovePrivateAS(localAS uint32, option config.RemovePrivateAsO
}
}
if len(newASParam) > 0 {
- newASParams = append(newASParams, bgp.NewAs4PathParam(asParam.Type, newASParam))
+ newASParams = append(newASParams, bgp.NewAs4PathParam(param.GetType(), newASParam))
}
}
path.setPathAttr(bgp.NewPathAttributeAsPath(newASParams))
@@ -826,10 +828,10 @@ func (path *Path) removeConfedAs() {
return
}
newAsParams := make([]bgp.AsPathParamInterface, 0, len(original.Value))
- for _, v := range original.Value {
- p := v.(*bgp.As4PathParam)
- if p.Type == bgp.BGP_ASPATH_ATTR_TYPE_SEQ || p.Type == bgp.BGP_ASPATH_ATTR_TYPE_SET {
- newAsParams = append(newAsParams, p)
+ for _, param := range original.Value {
+ switch param.GetType() {
+ case bgp.BGP_ASPATH_ATTR_TYPE_SEQ, bgp.BGP_ASPATH_ATTR_TYPE_SET:
+ newAsParams = append(newAsParams, param)
}
}
path.setPathAttr(bgp.NewPathAttributeAsPath(newAsParams))
@@ -843,16 +845,17 @@ func (path *Path) ReplaceAS(localAS, peerAS uint32) *Path {
newASParams := make([]bgp.AsPathParamInterface, 0, len(original.Value))
changed := false
for _, param := range original.Value {
- asParam := param.(*bgp.As4PathParam)
- newASParam := make([]uint32, 0, len(asParam.AS))
- for _, as := range asParam.AS {
+ segType := param.GetType()
+ asList := param.GetAS()
+ newASParam := make([]uint32, 0, len(asList))
+ for _, as := range asList {
if as == peerAS {
as = localAS
changed = true
}
newASParam = append(newASParam, as)
}
- newASParams = append(newASParams, bgp.NewAs4PathParam(asParam.Type, newASParam))
+ newASParams = append(newASParams, bgp.NewAs4PathParam(segType, newASParam))
}
if changed {
path = path.Clone(path.IsWithdraw)