Newer
Older
"github.com/taktv6/tflow2/convert"
bnet "github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/util/decode"
// MultiProtocolReachNLRI represents network layer reachability information for one prefix of an IP address family (rfc4760)
AFI uint16
SAFI uint8
NextHop bnet.IP
Prefixes []bnet.Prefix
func (n *MultiProtocolReachNLRI) serialize(buf *bytes.Buffer, opt *EncodeOptions) uint16 {
nextHop := n.NextHop.Bytes()
tempBuf := bytes.NewBuffer(nil)
tempBuf.Write(convert.Uint16Byte(n.AFI))
tempBuf.WriteByte(n.SAFI)
tempBuf.Write(nextHop)
tempBuf.WriteByte(0) // RESERVED
for _, pfx := range n.Prefixes {
tempBuf.Write(convert.Uint32Byte(n.PathID))
}
tempBuf.Write(serializePrefix(pfx))
}
func deserializeMultiProtocolReachNLRI(b []byte) (MultiProtocolReachNLRI, error) {
n := MultiProtocolReachNLRI{}
nextHopLength := uint8(0)
variableLength := len(b) - 4 // 4 <- AFI + SAFI + NextHopLength
if variableLength <= 0 {
return n, fmt.Errorf("Invalid length of MP_REACH_NLRI: expected more than 4 bytes but got %d", len(b))
}
variable := make([]byte, variableLength)
fields := []interface{}{
&n.AFI,
&n.SAFI,
&nextHopLength,
&variable,
}
err := decode.Decode(bytes.NewBuffer(b), fields)
if err != nil {
return MultiProtocolReachNLRI{}, err
}
budget := variableLength
if budget < int(nextHopLength) {
return MultiProtocolReachNLRI{},
fmt.Errorf("Failed to decode next hop IP: expected %d bytes for NLRI, only %d remaining", nextHopLength, budget)
}
n.NextHop, err = bnet.IPFromBytes(variable[:nextHopLength])
if err != nil {
return MultiProtocolReachNLRI{}, fmt.Errorf("Failed to decode next hop IP: %v", err)
}
n.Prefixes = make([]bnet.Prefix, 0)
variable = variable[1+nextHopLength:] // 1 <- RESERVED field
idx := uint16(0)
for idx < uint16(len(variable)) {
pfxLen := variable[idx]
idx++
r := uint16(len(variable)) - idx
if r < numBytes {
return MultiProtocolReachNLRI{}, fmt.Errorf("expected %d bytes for NLRI, only %d remaining", numBytes, r)
start := idx
end := idx + numBytes
pfx, err := deserializePrefix(variable[start:end], pfxLen, n.AFI)
if err != nil {
return MultiProtocolReachNLRI{}, err
}
n.Prefixes = append(n.Prefixes, pfx)