summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-07-05 18:29:06 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-07-05 23:44:22 +0900
commit84f1e917e78be7686e676f1d6cc0810ee499e561 (patch)
treef014a79f80b923b78b0065ee470efbe9c934e191
parent2fc9b887fc63da94e173f75dd15330254e35647c (diff)
packet: fix bug of not taking care of withdrawn label
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--packet/bgp.go20
-rw-r--r--packet/bgp_test.go23
2 files changed, 42 insertions, 1 deletions
diff --git a/packet/bgp.go b/packet/bgp.go
index 6cc9145d..b95d48f3 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -852,7 +852,7 @@ func getRouteDistinguisher(data []byte) RouteDistinguisherInterface {
//
// RFC3107 Carrying Label Information in BGP-4
//
-// 4. Carrying Label Mapping Information
+// 3. Carrying Label Mapping Information
//
// b) Label:
//
@@ -872,6 +872,14 @@ func getRouteDistinguisher(data []byte) RouteDistinguisherInterface {
// +-----+-+-+---+-+-+-+-+-+-----+-+-+-+
//
+// RFC3107 Carrying Label Information in BGP-4
+//
+// 3. Carrying Label Mapping Information
+//
+// The label information carried (as part of NLRI) in the Withdrawn
+// Routes field should be set to 0x800000.
+const WITHDRAW_LABEL = uint32(0x800000)
+
type MPLSLabelStack struct {
Labels []uint32
}
@@ -881,6 +889,10 @@ func (l *MPLSLabelStack) DecodeFromBytes(data []byte) error {
foundBottom := false
for len(data) >= 3 {
label := uint32(data[0])<<16 | uint32(data[1])<<8 | uint32(data[2])
+ if label == WITHDRAW_LABEL {
+ l.Labels = []uint32{label}
+ return nil
+ }
data = data[3:]
labels = append(labels, label>>4)
if label&1 == 1 {
@@ -899,6 +911,9 @@ func (l *MPLSLabelStack) DecodeFromBytes(data []byte) error {
func (l *MPLSLabelStack) Serialize() ([]byte, error) {
buf := make([]byte, len(l.Labels)*3)
for i, label := range l.Labels {
+ if label == WITHDRAW_LABEL {
+ return []byte{128, 0, 0}, nil
+ }
label = label << 4
buf[i*3] = byte((label >> 16) & 0xff)
buf[i*3+1] = byte((label >> 8) & 0xff)
@@ -911,6 +926,9 @@ func (l *MPLSLabelStack) Serialize() ([]byte, error) {
func (l *MPLSLabelStack) Len() int { return 3 * len(l.Labels) }
func NewMPLSLabelStack(labels ...uint32) *MPLSLabelStack {
+ if len(labels) == 0 {
+ labels = []uint32{0}
+ }
return &MPLSLabelStack{labels}
}
diff --git a/packet/bgp_test.go b/packet/bgp_test.go
index 84aaed75..286bd27c 100644
--- a/packet/bgp_test.go
+++ b/packet/bgp_test.go
@@ -360,3 +360,26 @@ func Test_ASLen(t *testing.T) {
assert.Equal(0, as4path.ASLen())
}
+
+func Test_MPLSLabelStack(t *testing.T) {
+ assert := assert.New(t)
+ mpls := NewMPLSLabelStack()
+ buf, err := mpls.Serialize()
+ assert.Nil(err)
+ assert.Equal(true, bytes.Equal(buf, []byte{0, 0, 1}))
+
+ mpls = &MPLSLabelStack{}
+ assert.Nil(mpls.DecodeFromBytes(buf))
+ assert.Equal(1, len(mpls.Labels))
+ assert.Equal(uint32(0), mpls.Labels[0])
+
+ mpls = NewMPLSLabelStack(WITHDRAW_LABEL)
+ buf, err = mpls.Serialize()
+ assert.Nil(err)
+ assert.Equal(true, bytes.Equal(buf, []byte{128, 0, 0}))
+
+ mpls = &MPLSLabelStack{}
+ assert.Nil(mpls.DecodeFromBytes(buf))
+ assert.Equal(1, len(mpls.Labels))
+ assert.Equal(WITHDRAW_LABEL, mpls.Labels[0])
+}