summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go19
-rw-r--r--api/gobgp.proto7
-rw-r--r--gobgp/neighbor.go39
-rw-r--r--packet/bgp.go29
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,
}
}