From 264bd0ca126bf721687764332a01315d56e5b671 Mon Sep 17 00:00:00 2001 From: IWASE Yusuke Date: Tue, 27 Feb 2018 09:49:35 +0900 Subject: 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 --- table/destination.go | 15 +++++----- table/message.go | 48 ++++++++++++++++------------- table/path.go | 85 +++++++++++++++++++++++++++------------------------- 3 files changed, 80 insertions(+), 68 deletions(-) (limited to 'table') 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) -- cgit v1.2.3