diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-03-01 12:55:28 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-03-02 16:07:27 +0900 |
commit | eb5442d87fde9e47cda327ca10a17e17bf978a44 (patch) | |
tree | baa119f9249783eee111fab40a24e552ab1d73f0 | |
parent | 55e96842593e9645ea0866398d57cfa8a8530385 (diff) |
zebra/zapi: Utility func to decode/serialize nexthops
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r-- | zebra/zapi.go | 204 |
1 files changed, 101 insertions, 103 deletions
diff --git a/zebra/zapi.go b/zebra/zapi.go index e967eaf6..d43362bb 100644 --- a/zebra/zapi.go +++ b/zebra/zapi.go @@ -854,6 +854,87 @@ func (n *Nexthop) String() string { return s } +func serializeNexthops(nexthops []*Nexthop, isV4 bool) ([]byte, error) { + buf := make([]byte, 0) + if len(nexthops) == 0 { + return buf, nil + } + buf = append(buf, byte(len(nexthops))) + + for _, nh := range nexthops { + buf = append(buf, byte(nh.Type)) + + switch nh.Type { + case NEXTHOP_IFINDEX, NEXTHOP_IFNAME: + bbuf := make([]byte, 4) + binary.BigEndian.PutUint32(bbuf, nh.Ifindex) + buf = append(buf, bbuf...) + + case NEXTHOP_IPV4, NEXTHOP_IPV6: + if isV4 { + buf = append(buf, nh.Addr.To4()...) + } else { + buf = append(buf, nh.Addr.To16()...) + } + + case NEXTHOP_IPV4_IFINDEX, NEXTHOP_IPV4_IFNAME, NEXTHOP_IPV6_IFINDEX, NEXTHOP_IPV6_IFNAME: + if isV4 { + buf = append(buf, nh.Addr.To4()...) + } else { + buf = append(buf, nh.Addr.To16()...) + } + bbuf := make([]byte, 4) + binary.BigEndian.PutUint32(bbuf, nh.Ifindex) + buf = append(buf, bbuf...) + } + } + + return buf, nil +} + +func decodeNexthopsFromBytes(nexthops *[]*Nexthop, data []byte, isV4 bool) (int, error) { + addrLen := net.IPv4len + if !isV4 { + addrLen = net.IPv6len + } + + numNexthop := int(data[0]) + offset := 1 + + for i := 0; i < numNexthop; i++ { + nh := &Nexthop{} + nh.Type = NEXTHOP_FLAG(data[offset]) + offset += 1 + + switch nh.Type { + case NEXTHOP_IFINDEX, NEXTHOP_IFNAME: + nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + + case NEXTHOP_IPV4, NEXTHOP_IPV6: + if isV4 { + nh.Addr = net.IP(data[offset : offset+addrLen]).To4() + } else { + nh.Addr = net.IP(data[offset : offset+addrLen]).To16() + } + offset += addrLen + + case NEXTHOP_IPV4_IFINDEX, NEXTHOP_IPV4_IFNAME, NEXTHOP_IPV6_IFINDEX, NEXTHOP_IPV6_IFNAME: + if isV4 { + nh.Addr = net.IP(data[offset : offset+addrLen]).To4() + } else { + nh.Addr = net.IP(data[offset : offset+addrLen]).To16() + } + offset += addrLen + nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + } + *nexthops = append(*nexthops, nh) + } + + return offset, nil +} + func (b *NexthopLookupBody) Serialize() ([]byte, error) { isV4 := b.Api == IPV4_NEXTHOP_LOOKUP @@ -870,12 +951,12 @@ func (b *NexthopLookupBody) Serialize() ([]byte, error) { func (b *NexthopLookupBody) DecodeFromBytes(data []byte, version uint8) error { isV4 := b.Api == IPV4_NEXTHOP_LOOKUP - var addrLen uint8 = net.IPv4len + addrLen := net.IPv4len if !isV4 { addrLen = net.IPv6len } - if len(data) < int(addrLen) { + if len(data) < addrLen { return fmt.Errorf("message length invalid") } @@ -892,45 +973,11 @@ func (b *NexthopLookupBody) DecodeFromBytes(data []byte, version uint8) error { if len(data[pos:]) > int(1+addrLen) { b.Metric = binary.BigEndian.Uint32(data[pos : pos+4]) pos += 4 - nexthopNum := int(data[pos]) b.Nexthops = []*Nexthop{} - - if nexthopNum > 0 { - pos += 1 - for i := 0; i < nexthopNum; i++ { - nh := &Nexthop{} - nh.Type = NEXTHOP_FLAG(data[pos]) - pos += 1 - - switch nh.Type { - case NEXTHOP_IPV4, NEXTHOP_IPV6: - b := make([]byte, addrLen) - copy(b, data[pos:pos+addrLen]) - if isV4 { - nh.Addr = net.IP(b).To4() - } else { - nh.Addr = net.IP(b).To16() - } - pos += addrLen - - case NEXTHOP_IPV4_IFINDEX, NEXTHOP_IPV6_IFINDEX, NEXTHOP_IPV6_IFNAME: - b := make([]byte, addrLen) - copy(b, data[pos:pos+addrLen]) - if isV4 { - nh.Addr = net.IP(b).To4() - } else { - nh.Addr = net.IP(b).To16() - } - pos += addrLen - nh.Ifindex = binary.BigEndian.Uint32(data[pos : pos+4]) - pos += 4 - - case NEXTHOP_IFINDEX, NEXTHOP_IFNAME: - nh.Ifindex = binary.BigEndian.Uint32(data[pos : pos+4]) - pos += 4 - } - b.Nexthops = append(b.Nexthops, nh) - } + if nexthopsByteLen, err := decodeNexthopsFromBytes(&b.Nexthops, data[pos:], isV4); err != nil { + return err + } else { + pos += nexthopsByteLen } } @@ -964,10 +1011,13 @@ func (b *ImportLookupBody) Serialize() ([]byte, error) { } func (b *ImportLookupBody) DecodeFromBytes(data []byte, version uint8) error { + isV4 := b.Api == IPV4_IMPORT_LOOKUP + addrLen := net.IPv4len + if !isV4 { + addrLen = net.IPv6len + } - var addrLen uint8 = net.IPv4len - - if len(data) < int(addrLen) { + if len(data) < addrLen { return fmt.Errorf("message length invalid") } @@ -980,36 +1030,11 @@ func (b *ImportLookupBody) DecodeFromBytes(data []byte, version uint8) error { if len(data[pos:]) > int(1+addrLen) { b.Metric = binary.BigEndian.Uint32(data[pos : pos+4]) pos += 4 - nexthopNum := int(data[pos]) b.Nexthops = []*Nexthop{} - if nexthopNum > 0 { - pos += 1 - for i := 0; i < nexthopNum; i++ { - nh := &Nexthop{} - nh.Type = NEXTHOP_FLAG(data[pos]) - pos += 1 - - switch nh.Type { - case NEXTHOP_IPV4: - b := make([]byte, addrLen) - copy(b, data[pos:pos+addrLen]) - nh.Addr = net.IP(b).To4() - pos += addrLen - - case NEXTHOP_IPV4_IFINDEX: - b := make([]byte, addrLen) - copy(b, data[pos:pos+addrLen]) - nh.Addr = net.IP(b).To4() - pos += addrLen - nh.Ifindex = binary.BigEndian.Uint32(data[pos : pos+4]) - pos += 4 - - case NEXTHOP_IFINDEX, NEXTHOP_IFNAME: - nh.Ifindex = binary.BigEndian.Uint32(data[pos : pos+4]) - pos += 4 - } - b.Nexthops = append(b.Nexthops, nh) - } + if nexthopsByteLen, err := decodeNexthopsFromBytes(&b.Nexthops, data[pos:], isV4); err != nil { + return err + } else { + pos += nexthopsByteLen } } @@ -1205,40 +1230,13 @@ func (b *NexthopUpdateBody) DecodeFromBytes(data []byte, version uint8) error { } b.Metric = binary.BigEndian.Uint32(data[offset : offset+4]) offset += 4 - nexthopsNum := int(data[offset]) - offset += 1 // List of Nexthops b.Nexthops = []*Nexthop{} - for i := 0; i < nexthopsNum; i++ { - nh := &Nexthop{} - nh.Type = NEXTHOP_FLAG(data[offset]) - offset += 1 - - switch nh.Type { - case NEXTHOP_IPV4, NEXTHOP_IPV6: - if isV4 { - nh.Addr = net.IP(data[offset : offset+addrLen]).To4() - } else { - nh.Addr = net.IP(data[offset : offset+addrLen]).To16() - } - offset += addrLen - - case NEXTHOP_IPV4_IFINDEX, NEXTHOP_IPV4_IFNAME, NEXTHOP_IPV6_IFINDEX, NEXTHOP_IPV6_IFNAME: - if isV4 { - nh.Addr = net.IP(data[offset : offset+addrLen]).To4() - } else { - nh.Addr = net.IP(data[offset : offset+addrLen]).To16() - } - offset += addrLen - nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4]) - offset += 4 - - case NEXTHOP_IFINDEX, NEXTHOP_IFNAME: - nh.Ifindex = binary.BigEndian.Uint32(data[offset : offset+4]) - offset += 4 - } - b.Nexthops = append(b.Nexthops, nh) + if nexthopsByteLen, err := decodeNexthopsFromBytes(&b.Nexthops, data[offset:], isV4); err != nil { + return err + } else { + offset += nexthopsByteLen } return nil |