func newIPRouteMessage(dst []*table.Path, version uint8, vrfId uint16) *zebra.Message { paths := make([]*table.Path, 0, len(dst)) for _, path := range dst { if path == nil || path.IsFromExternal() { continue } paths = append(paths, path) } if len(paths) == 0 { return nil } path := paths[0] l := strings.SplitN(path.GetNlri().String(), "/", 2) var command zebra.API_TYPE var prefix net.IP nexthops := make([]net.IP, 0, len(paths)) switch path.GetRouteFamily() { case bgp.RF_IPv4_UC, bgp.RF_IPv4_VPN: if path.IsWithdraw == true { command = zebra.IPV4_ROUTE_DELETE } else { command = zebra.IPV4_ROUTE_ADD } if path.GetRouteFamily() == bgp.RF_IPv4_UC { prefix = path.GetNlri().(*bgp.IPAddrPrefix).IPAddrPrefixDefault.Prefix.To4() } else { prefix = path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).IPAddrPrefixDefault.Prefix.To4() } for _, p := range paths { nexthops = append(nexthops, p.GetNexthop().To4()) } case bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN: if path.IsWithdraw == true { command = zebra.IPV6_ROUTE_DELETE } else { command = zebra.IPV6_ROUTE_ADD } if path.GetRouteFamily() == bgp.RF_IPv6_UC { prefix = path.GetNlri().(*bgp.IPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() } else { prefix = path.GetNlri().(*bgp.LabeledVPNIPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() } for _, p := range paths { nexthops = append(nexthops, p.GetNexthop().To16()) } default: return nil } flags := uint8(zebra.MESSAGE_NEXTHOP) plen, _ := strconv.Atoi(l[1]) med, err := path.GetMed() if err == nil { flags |= zebra.MESSAGE_METRIC } return &zebra.Message{ Header: zebra.Header{ Len: zebra.HeaderSize(version), Marker: zebra.HEADER_MARKER, Version: version, Command: command, VrfId: vrfId, }, Body: &zebra.IPRouteBody{ Type: zebra.ROUTE_BGP, SAFI: zebra.SAFI_UNICAST, Message: flags, Prefix: prefix, PrefixLength: uint8(plen), Nexthops: nexthops, Metric: med, }, } }
func Test_createRequestFromIPRouteMessage(t *testing.T) { assert := assert.New(t) m := &zebra.Message{} h := &zebra.Header{ Len: zebra.HeaderSize(2), Marker: zebra.HEADER_MARKER, Version: 2, Command: zebra.IPV4_ROUTE_ADD, } b := &zebra.IPRouteBody{ Type: zebra.ROUTE_TYPE(zebra.ROUTE_STATIC), Flags: zebra.FLAG(zebra.FLAG_SELECTED), Message: zebra.MESSAGE_NEXTHOP | zebra.MESSAGE_DISTANCE | zebra.MESSAGE_METRIC, SAFI: zebra.SAFI(zebra.SAFI_UNICAST), Prefix: net.ParseIP("192.168.100.0"), PrefixLength: uint8(24), Nexthops: []net.IP{net.ParseIP("0.0.0.0")}, Ifindexs: []uint32{1}, Distance: uint8(0), Metric: uint32(100), Api: zebra.API_TYPE(zebra.IPV4_ROUTE_ADD), } m.Header = *h m.Body = b path := createPathFromIPRouteMessage(m) pp := table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("0.0.0.0", pp.GetNexthop().String()) assert.Equal("192.168.100.0/24", pp.GetNlri().String()) assert.True(pp.IsFromExternal()) assert.False(pp.IsWithdraw) // withdraw h.Command = zebra.IPV4_ROUTE_DELETE m.Header = *h path = createPathFromIPRouteMessage(m) pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("0.0.0.0", pp.GetNexthop().String()) assert.Equal("192.168.100.0/24", pp.GetNlri().String()) med, _ := pp.GetMed() assert.Equal(uint32(100), med) assert.True(pp.IsFromExternal()) assert.True(pp.IsWithdraw) // IPv6 h.Command = zebra.IPV6_ROUTE_ADD b.Prefix = net.ParseIP("2001:db8:0:f101::") b.PrefixLength = uint8(64) b.Nexthops = []net.IP{net.ParseIP("::")} m.Header = *h m.Body = b path = createPathFromIPRouteMessage(m) pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("::", pp.GetNexthop().String()) assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String()) med, _ = pp.GetMed() assert.Equal(uint32(100), med) assert.True(pp.IsFromExternal()) assert.False(pp.IsWithdraw) // withdraw h.Command = zebra.IPV6_ROUTE_DELETE m.Header = *h path = createPathFromIPRouteMessage(m) pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false) pp.SetIsFromExternal(path.IsFromExternal()) assert.Equal("::", pp.GetNexthop().String()) assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String()) assert.True(pp.IsFromExternal()) assert.True(pp.IsWithdraw) }