summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packet/bgp/bgp.go10
-rw-r--r--server/fsm.go26
-rw-r--r--table/message.go53
3 files changed, 74 insertions, 15 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index 8a793720..9d6678d3 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -4439,7 +4439,7 @@ func NewPathAttributeAtomicAggregate() *PathAttributeAtomicAggregate {
type PathAttributeAggregatorParam struct {
AS uint32
- askind reflect.Kind
+ Askind reflect.Kind
Address net.IP
}
@@ -4461,18 +4461,18 @@ func (p *PathAttributeAggregator) DecodeFromBytes(data []byte) error {
if len(p.PathAttribute.Value) == 6 {
p.Value.AS = uint32(binary.BigEndian.Uint16(p.PathAttribute.Value[0:2]))
p.Value.Address = p.PathAttribute.Value[2:]
- p.Value.askind = reflect.Uint16
+ p.Value.Askind = reflect.Uint16
} else {
p.Value.AS = binary.BigEndian.Uint32(p.PathAttribute.Value[0:4])
p.Value.Address = p.PathAttribute.Value[4:]
- p.Value.askind = reflect.Uint32
+ p.Value.Askind = reflect.Uint32
}
return nil
}
func (p *PathAttributeAggregator) Serialize() ([]byte, error) {
var buf []byte
- switch p.Value.askind {
+ switch p.Value.Askind {
case reflect.Uint16:
buf = make([]byte, 6)
binary.BigEndian.PutUint16(buf, uint16(p.Value.AS))
@@ -4513,7 +4513,7 @@ func NewPathAttributeAggregator(as interface{}, address string) *PathAttributeAg
},
Value: PathAttributeAggregatorParam{
AS: uint32(v.Uint()),
- askind: v.Kind(),
+ Askind: v.Kind(),
Address: net.ParseIP(address).To4(),
},
}
diff --git a/server/fsm.go b/server/fsm.go
index e0fb53c2..e80c6512 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -634,18 +634,23 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
} else {
// FIXME: we should use the original message for bmp/mrt
table.UpdatePathAttrs4ByteAs(body)
- fmsg.PathList = table.ProcessMessage(m, h.fsm.peerInfo, fmsg.timestamp)
- id := h.fsm.pConf.Config.NeighborAddress
- policyMutex.RLock()
- for _, path := range fmsg.PathList {
- if path.IsEOR() {
- continue
- }
- if h.fsm.policy.ApplyPolicy(id, table.POLICY_DIRECTION_IN, path, nil) == nil {
- path.Filter(id, table.POLICY_DIRECTION_IN)
+ err := table.UpdatePathAggregator4ByteAs(body)
+ if err == nil {
+ fmsg.PathList = table.ProcessMessage(m, h.fsm.peerInfo, fmsg.timestamp)
+ id := h.fsm.pConf.Config.NeighborAddress
+ policyMutex.RLock()
+ for _, path := range fmsg.PathList {
+ if path.IsEOR() {
+ continue
+ }
+ if h.fsm.policy.ApplyPolicy(id, table.POLICY_DIRECTION_IN, path, nil) == nil {
+ path.Filter(id, table.POLICY_DIRECTION_IN)
+ }
}
+ policyMutex.RUnlock()
+ } else {
+ fmsg.MsgData = err
}
- policyMutex.RUnlock()
}
fmsg.payload = make([]byte, len(headerBuf)+len(bodyBuf))
copy(fmsg.payload, headerBuf)
@@ -1009,6 +1014,7 @@ func (h *FSMHandler) sendMessageloop() error {
"Data": m,
}).Debug("update for 2byte AS peer")
table.UpdatePathAttrs2ByteAs(m.Body.(*bgp.BGPUpdate))
+ table.UpdatePathAggregator2ByteAs(m.Body.(*bgp.BGPUpdate))
}
b, err := m.Serialize()
if err != nil {
diff --git a/table/message.go b/table/message.go
index 5cf9b5b6..68801e73 100644
--- a/table/message.go
+++ b/table/message.go
@@ -20,6 +20,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet/bgp"
"hash/fnv"
+ "reflect"
)
func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
@@ -198,6 +199,58 @@ func UpdatePathAttrs4ByteAs(msg *bgp.BGPUpdate) error {
return nil
}
+func UpdatePathAggregator2ByteAs(msg *bgp.BGPUpdate) {
+ as := uint32(0)
+ var addr string
+ for _, attr := range msg.PathAttributes {
+ switch attr.(type) {
+ case *bgp.PathAttributeAggregator:
+ agg := attr.(*bgp.PathAttributeAggregator)
+ agg.Value.Askind = reflect.Uint16
+ if agg.Value.AS > (1<<16)-1 {
+ as = agg.Value.AS
+ addr = agg.Value.Address.String()
+ agg.Value.AS = bgp.AS_TRANS
+ }
+ }
+ }
+ if as != 0 {
+ msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Aggregator(as, addr))
+ }
+}
+
+func UpdatePathAggregator4ByteAs(msg *bgp.BGPUpdate) error {
+ var aggAttr *bgp.PathAttributeAggregator
+ var agg4Attr *bgp.PathAttributeAs4Aggregator
+ agg4AttrPos := 0
+ for i, attr := range msg.PathAttributes {
+ switch attr.(type) {
+ case *bgp.PathAttributeAggregator:
+ attr := attr.(*bgp.PathAttributeAggregator)
+ if attr.Value.Askind == reflect.Uint16 {
+ aggAttr = attr
+ aggAttr.Value.Askind = reflect.Uint32
+ }
+ case *bgp.PathAttributeAs4Aggregator:
+ agg4Attr = attr.(*bgp.PathAttributeAs4Aggregator)
+ agg4AttrPos = i
+ }
+ }
+ if aggAttr == nil && agg4Attr == nil {
+ return nil
+ }
+
+ if aggAttr == nil && agg4Attr != nil {
+ return bgp.NewMessageError(bgp.BGP_ERROR_UPDATE_MESSAGE_ERROR, bgp.BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "AS4 AGGREGATOR attribute exists, but AGGREGATOR doesn't")
+ }
+
+ if agg4Attr != nil {
+ msg.PathAttributes = append(msg.PathAttributes[:agg4AttrPos], msg.PathAttributes[agg4AttrPos+1:]...)
+ aggAttr.Value.AS = agg4Attr.Value.AS
+ }
+ return nil
+}
+
func createUpdateMsgFromPath(path *Path, msg *bgp.BGPMessage) *bgp.BGPMessage {
rf := path.GetRouteFamily()