diff options
-rw-r--r-- | api/gobgp.pb.go | 19 | ||||
-rw-r--r-- | api/gobgp.proto | 7 | ||||
-rw-r--r-- | gobgp/neighbor.go | 39 | ||||
-rw-r--r-- | packet/bgp.go | 29 |
4 files changed, 76 insertions, 18 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index 5df8c325..132701c1 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -26,6 +26,7 @@ It has these top-level messages: TunnelEncapSubTLV TunnelEncapTLV PathAttr + AsPath Path Destination PeerConf @@ -767,7 +768,7 @@ type PathAttr struct { Type BGP_ATTR_TYPE `protobuf:"varint,1,opt,name=type,enum=api.BGP_ATTR_TYPE" json:"type,omitempty"` Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` Origin Origin `protobuf:"varint,3,opt,name=origin,enum=api.Origin" json:"origin,omitempty"` - AsPath []uint32 `protobuf:"varint,4,rep,name=as_path" json:"as_path,omitempty"` + AsPaths []*AsPath `protobuf:"bytes,4,rep,name=as_paths" json:"as_paths,omitempty"` Nexthop string `protobuf:"bytes,5,opt,name=nexthop" json:"nexthop,omitempty"` Metric uint32 `protobuf:"varint,6,opt,name=metric" json:"metric,omitempty"` Pref uint32 `protobuf:"varint,7,opt,name=pref" json:"pref,omitempty"` @@ -783,6 +784,13 @@ func (m *PathAttr) Reset() { *m = PathAttr{} } func (m *PathAttr) String() string { return proto.CompactTextString(m) } func (*PathAttr) ProtoMessage() {} +func (m *PathAttr) GetAsPaths() []*AsPath { + if m != nil { + return m.AsPaths + } + return nil +} + func (m *PathAttr) GetAggregator() *Aggregator { if m != nil { return m.Aggregator @@ -804,6 +812,15 @@ func (m *PathAttr) GetTunnelEncap() []*TunnelEncapTLV { return nil } +type AsPath struct { + SegmentType uint32 `protobuf:"varint,1,opt,name=segment_type" json:"segment_type,omitempty"` + Asns []uint32 `protobuf:"varint,2,rep,name=asns" json:"asns,omitempty"` +} + +func (m *AsPath) Reset() { *m = AsPath{} } +func (m *AsPath) String() string { return proto.CompactTextString(m) } +func (*AsPath) ProtoMessage() {} + type Path struct { Nlri *Nlri `protobuf:"bytes,1,opt,name=nlri" json:"nlri,omitempty"` Nexthop string `protobuf:"bytes,2,opt,name=nexthop" json:"nexthop,omitempty"` diff --git a/api/gobgp.proto b/api/gobgp.proto index 9bb0075f..0d38ad58 100644 --- a/api/gobgp.proto +++ b/api/gobgp.proto @@ -277,7 +277,7 @@ message PathAttr { BGP_ATTR_TYPE type = 1; repeated string value = 2; Origin origin = 3; - repeated uint32 as_path = 4; + repeated AsPath as_paths = 4; string nexthop = 5; uint32 metric = 6; uint32 pref = 7; @@ -289,6 +289,11 @@ message PathAttr { repeated TunnelEncapTLV tunnel_encap = 13; } +message AsPath { + uint32 segment_type = 1; + repeated uint32 asns = 2; +} + message Path { Nlri nlri = 1; string nexthop = 2; diff --git a/gobgp/neighbor.go b/gobgp/neighbor.go index 71044386..65bf6a85 100644 --- a/gobgp/neighbor.go +++ b/gobgp/neighbor.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/jessevdk/go-flags" "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/packet" "github.com/osrg/gobgp/policy" "golang.org/x/net/context" "io" @@ -262,6 +263,12 @@ func NewNeighborRibCommand(addr string, resource api.Resource, cmd string) *Neig } } +type AsPathFormat struct { + start string + end string + separator string +} + func showRoute(pathList []*api.Path, showAge bool, showBest bool) { var pathStrs [][]interface{} @@ -271,19 +278,35 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool) { for _, p := range pathList { aspath := func(attrs []*api.PathAttr) string { - s := bytes.NewBuffer(make([]byte, 0, 64)) - s.WriteString("[") + + delimiter := make(map[int]*AsPathFormat) + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SET] = &AsPathFormat{"{", "}", ","} + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SEQ] = &AsPathFormat{"", "", " "} + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ] = &AsPathFormat{"(", ")", " "} + delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET] = &AsPathFormat{"[", "]", ","} + + var segments []string = make([]string, 0) for _, a := range attrs { if a.Type == api.BGP_ATTR_TYPE_AS_PATH { - var ss []string - for _, as := range a.AsPath { - ss = append(ss, fmt.Sprintf("%d", as)) + aspaths := a.AsPaths + for _, aspath := range aspaths { + s := bytes.NewBuffer(make([]byte, 0, 64)) + t := int(aspath.SegmentType) + start := delimiter[t].start + end := delimiter[t].end + separator := delimiter[t].separator + s.WriteString(start) + var asnsStr []string + for _, asn := range aspath.Asns { + asnsStr = append(asnsStr, fmt.Sprintf("%d", asn)) + } + s.WriteString(strings.Join(asnsStr, separator)) + s.WriteString(end) + segments = append(segments, s.String()) } - s.WriteString(strings.Join(ss, " ")) } } - s.WriteString("]") - return s.String() + return strings.Join(segments, " ") } formatAttrs := func(attrs []*api.PathAttr) string { s := []string{} diff --git a/packet/bgp.go b/packet/bgp.go index a5175bca..533b0288 100644 --- a/packet/bgp.go +++ b/packet/bgp.go @@ -55,6 +55,8 @@ const ( const ( BGP_ASPATH_ATTR_TYPE_SET = 1 BGP_ASPATH_ATTR_TYPE_SEQ = 2 + BGP_ASPATH_ATTR_TYPE_CONFED_SEQ = 3 + BGP_ASPATH_ATTR_TYPE_CONFED_SET = 4 ) // RFC7153 5.1. Registries for the "Type" Field @@ -2168,21 +2170,27 @@ func (p *PathAttributeAsPath) Serialize() ([]byte, error) { } func (p *PathAttributeAsPath) ToApiStruct() *api.PathAttr { - aslist := make([]uint32, 0) + aspaths := make([]*api.AsPath, 0) for _, a := range p.Value { path, y := a.(*As4PathParam) + aspath := &api.AsPath{} if y { - aslist = append(aslist, path.AS...) + aspath.Asns = path.AS + aspath.SegmentType = uint32(path.Type) } else { path := a.(*AsPathParam) + asns := make([]uint32, 0) for _, v := range path.AS { - aslist = append(aslist, uint32(v)) + asns = append(asns, uint32(v)) } + aspath.Asns = asns + aspath.SegmentType = uint32(path.Type) } + aspaths = append(aspaths, aspath) } return &api.PathAttr{ Type: api.BGP_ATTR_TYPE_AS_PATH, - AsPath: aslist, + AsPaths: aspaths, } } @@ -3279,13 +3287,18 @@ func (p *PathAttributeAs4Path) Serialize() ([]byte, error) { } func (p *PathAttributeAs4Path) ToApiStruct() *api.PathAttr { - aslist := make([]uint32, 0) + aspaths := make([]*api.AsPath, 0) + aspath := &api.AsPath{ + SegmentType: uint32(p.Type), + Asns: make([]uint32, 0), + } for _, a := range p.Value { - aslist = append(aslist, a.AS...) + aspath.Asns = append(aspath.Asns, a.AS...) } + aspaths = append(aspaths, aspath) return &api.PathAttr{ - Type: api.BGP_ATTR_TYPE_AS4_PATH, - AsPath: aslist, + Type: api.BGP_ATTR_TYPE_AS_PATH, + AsPaths: aspaths, } } |